我们有两个长度相等且不为空的整型数组 A 和 B 。我们可以交换 A[i] 和 B[i] 的元素。注意这两个元素在各自的序列中应该处于相同的位置。在交换过一些元素之后,数组 A 和 B 都应该是严格递增的(数组严格递增的条件仅为A[0] < A[1] < A[2] < … < A[A.length - 1])。给定数组 A 和 B ,请返回使得两个数组均保持严格递增状态的最小交换次数。假设给定的输入总是有效的。示例: 输入: A = [1,3,5,4], B = [1,2,3,7] 输出: 1
力扣(LeetCode)
确定状态
动态规划一般来讲,目标是求什么则什么即为状态,然后分析当前状态和之前状态的推导关系,进而进行穷举所有状态即可。
本题中使用dp[i][j] 表示第 i 个位置的元素,第 j (交换、不交换)状态时的最小次数。
初始状态
第 0 个位置可以交换,也可以不交换,即初始状态为:d[0][0] = 0、dp[0][1] = 1。
状态转移方程
根据题目要求一定存在结果,所以在第 i 个位置,有以下几种情况:
①.A、B 两个数组对应的位置都是有序、存在交叉
如上图,A[i-1] < A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] < A[i];此时位置 i 可以交换,也可以不交换,并且和上个位置的交换状态无关。
②.A、B 两个数组对应的位置都是有序、不在交叉
如上图,A[i-1] < A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] > A[i];此时位置 i 若选择不交换,则上个位置也不能交换、若选择交换,则上个位置也必须交换。
③.A、B 两个数组对应的位置有一个存在无序
如上图,A[i-1] > A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] < A[i];此时位置 i 若选择不交换,则上个位置必须交换、若选择交换,并且上个位置不能交换。
确认结果
数组末尾位置的状态值就是本题为结果,即 min(dp[A.size()-1][0],dp[A.size()-1][1]);
代码示例
class Solution {
public:
int minSwap(vector<int>& A, vector<int>& B) {
int res = 0;
vector<vector<int>> dp(A.size(),vector(2,0));
dp[0][0] = 0;
dp[0][1] = 1;
for(int i = 1;i < A.size();i++)
{
if(A[i-1]<A[i]&&B[i-1]<B[i]){
if(A[i-1]<B[i] && B[i-1]<A[i]){//任意交换或者不交换,取最优值
dp[i][0] = min(dp[i-1][0],dp[i-1][1]);
dp[i][1] = 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 min(dp[A.size()-1][0],dp[A.size()-1][1]);
}
};