【Lintcode】1016. Minimum Swaps To Make Sequences Increasing
技術標籤:LC 貪心、動態規劃與記憶化搜尋演算法javaleetcode動態規劃
題目地址:
https://www.lintcode.com/problem/1016
給定兩個長度相等的陣列 A A A和 B B B,其長度都是 n n n。對於任意 i i i,允許交換 A [ i ] A[i] A[i]和 B [ i ] B[i] B[i],使得兩個陣列都嚴格遞增。問最少要交換多少次。題目保證解存在。
思路是動態規劃。設
f
[
i
]
f[i]
f[i]是不交換
A
[
i
]
A[i]
A[i]和
B
[
i
]
B[i]
B[i]的滿足條件的最小交換次數,
g
[
i
]
g[i]
1、如果
A
[
i
]
>
A
[
i
−
1
]
A[i]>A[i-1]
A[i]>A[i−1]和
B
[
i
]
>
B
[
i
−
1
]
B[i]>B[i-1]
B[i]>B[i−1]有一個不成立,分兩種情況,如果不交換
A
[
i
]
A[i]
A[i]和
B
[
i
]
B[i]
B[i]的話,
A
[
i
−
1
]
A[i-1]
A[i−1]和
B
[
i
−
1
]
B[i-1]
B[i−1]必須交換,所以
f
[
i
]
=
g
[
i
−
1
]
f[i]=g[i-1]
2、如果
A
[
i
]
>
A
[
i
−
1
]
A[i]>A[i-1]
A[i]>A[i−1]和
B
[
i
]
>
B
[
i
−
1
]
B[i]>B[i-1]
B[i]>B[i−1]同時成立,分兩種情況,如果
A
[
i
]
>
B
[
i
−
1
]
A[i]>B[i-1]
程式碼如下:
public class Solution {
/**
* @param A: an array
* @param B: an array
* @return: the minimum number of swaps to make both sequences strictly increasing
*/
public int minSwap(int[] A, int[] B) {
// Write your code here
int n = A.length;
if (n == 0) {
return 0;
}
int[][] dp = new int[n][2];
dp[0][0] = 0;
dp[0][1] = 1;
for (int i = 1; i < n; i++) {
if (A[i] > A[i - 1] && B[i] > B[i - 1]) {
if (A[i] > B[i - 1] && B[i] > A[i - 1]) {
dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][1]) + 1;
} else {
dp[i][0] = dp[i - 1][0];
dp[i][1] = dp[i - 1][1] + 1;
}
} else {
dp[i][0] = dp[i - 1][1];
dp[i][1] = dp[i - 1][0] + 1;
}
}
return Math.min(dp[n - 1][0], dp[n - 1][1]);
}
}
時空複雜度 O ( n ) O(n) O(n)。