Leetcode 629 K個逆序對陣列 C

2021-10-08 10:04:40 字數 1193 閱讀 2179

給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。

逆序對的定義如下:對於陣列的第i個和第 j個元素,如果滿i < j且 a[i] > a[j],則其為乙個逆序對;否則不是。

由於答案可能很大,只需要返回 答案 mod 109 + 7 的值。

示例 1:

輸入: n = 3, k = 0

輸出: 1

解釋:

只有陣列 [1,2,3] 包含了從1到3的整數並且正好擁有 0 個逆序對。

示例 2:

輸入: n = 3, k = 1

輸出: 2

解釋:

陣列 [1,3,2] 和 [2,1,3] 都有 1 個逆序對。

說明:

n 的範圍是 [1, 1000] 並且 k 的範圍是 [0, 1000]。

動態規劃

dp[i][j]表示前i的數字,恰好擁有j個逆序對,也就是1~i擁有j個逆序對

初始條件dp[0][0] = 1

轉移方程dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + dp[i-1][j-2] + ······+dp[i-1][j-i+1]

也就是我們考慮dp[i][j] 時需要考慮i這個數字的存放位置,我們可以放在最後乙個位置,那麼逆序對會增加0個,也就是我們需要考慮dp[i-1][j];我們可以放在倒數第二個位置,那麼逆序對會增加1個,我們就需要考慮dp[i-1][j-1],依次類推。

但是,這樣的時間複雜度為o(n2k),我們可以對其進行優化。

我們不妨令j=j-1,那麼dp[i][j-1] = dp[i-1][j-1] + dp[i-1][j-2] + dp[i-1][j-3] + ······+dp[i-1][j-i]

我們讓dp[i][j]-dp[i][j-1],得到dp[i][j] = dp[i-1][j] - dp[i-1][j-i] + dp[i][j-1],因此可以把時間複雜度變為o(nk)。詳細過程見**

int

kinversepairs

(int n,

int k)}}

return dp[n]

[k];

}

Leetcode 629 K個逆序對陣列

給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。逆序對的定義如下 對於陣列的第i個和第 j個元素,如果滿i j且 a i a j 則其為乙個逆序對 否則不是。由於答案可能很大,只需要返回 答案 mod 109 7 的值。示例 1 輸入 n 3...

LeetCode 629 K個逆序對陣列

略。首先,1 n 這 n 個數所能產生的最大逆序對為 n n 1 2 對。設 dp i j 表示 1 i 能產生 j 對逆序對的排列種數。這裡定義一下如果下標為負數,這一項為 0。在考慮接下來乙個事實 對於序列 1,2,3,4,5 和 2,5,7,9,10,在這個問題下,我可以說這兩個序列是等價的,...

629 K個逆序對陣列

給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。逆序對的定義如下 對於陣列的第i個和第 j個元素,如果滿i j且 a i a j 則其為乙個逆序對 否則不是。由於答案可能很大,只需要返回 答案 mod 109 7 的值。示例 1 輸入 n 3...