Minimum Swaps To Make Sequences Increasing

Minimum Swaps To Make Sequences Increasing

You are given two integer arrays of the same length nums1 and nums2 . In one operation, you are allowed to swap nums1[i] with nums2[i] .

  • For example, if nums1 = [1,2,3,8] , and nums2 = [5,6,7,4] , you can swap the element at i = 3 to obtain nums1 = [1,2,3,4] and nums2 = [5,6,7,8] .

Return the minimum number of needed operations to make nums1 and nums2 strictly increasing. The test cases are generated so that the given input always makes it possible.

An array arr is strictly increasing if and only if arr[0] < arr[1] < arr[2] < ... < arr[arr.length - 1] .

Example 1:

Input: nums1 = [1,3,5,4], nums2 = [1,2,3,7]
Output: 1
Explanation: 
Swap nums1[3] and nums2[3]. Then the sequences are:
nums1 = [1, 3, 5, 7] and nums2 = [1, 2, 3, 4]
which are both strictly increasing.

Example 2:

Input: nums1 = [0,3,5,8,9], nums2 = [2,1,4,6,9]
Output: 1

Constraints:

2nums1.length105
nums2.length==nums1.length
0nums1[i],nums2[i]2×105

 

解题思路

  写的时候一直以为是贪心那一类的思维题,结果想了半天都没想到怎么写,看题解才知道正解是dp,都傻掉了。其实一开始有想到爆搜,因为每个位置有换和不换两种选择,所以可以爆搜每个位置的选择,最后判断交换后的序列是否严格升序就可以了。其实想到这里就可以用dp了啊!先尝试定义一个一维状态f(i)表示将区间[0,i]变成升序的所有方案的集合。在状态转移的时候发现无法转移,因为不知道第i1个位置是否有交换过,所以不知道跟哪个数比较,因此还需要额外加多一个状态用来表示是否交换过。

  定义状态f(i,0)f(i,1),其中f(i,0)表示将区间[0,i]变成升序且第i个位置没有交换的所有方案的集合,f(i,1)表示将区间[0,i]变成升序且第i个位置有交换的所有方案的集合。属性就是最小值。状态转移如下:

  • 如果第i1个位置没有交换:
    • 如果n1[i1]<n1[i]并且n2[i1]<n2[i],那么f[i][0]=min(f[i][0],f[i1][0])
    • 如果n1[i1]<n2[i]并且n2[i1]<n1[i],那么f[i][1]=min(f[i][1],f[i1][0]+1)
  • 如果第i1个位置有交换:
    • 如果n2[i1]<n1[i]并且n1[i1]<n2[i],那么f[i][0]=min(f[i][0],f[i1][1])
    • 如果n2[i1]<n2[i]并且n1[i1]<n1[i],那么f[i][1]=min(f[i][1],f[i1][1]+1)

  AC代码如下:

复制代码
 1 class Solution {
 2 public:
 3     int minSwap(vector<int>& nums1, vector<int>& nums2) {
 4         int n = nums1.size();
 5         vector<vector<int>> f(n, vector<int>(2, n));
 6         f[0][0] = 0, f[0][1] = 1;
 7         for (int i = 1; i < n; i++) {
 8             if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) f[i][0] = f[i - 1][0], f[i][1] = f[i - 1][1] + 1;
 9             if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) f[i][0] = min(f[i][0], f[i - 1][1]), f[i][1] = min(f[i][1], f[i - 1][0] + 1);
10         }
11         return min(f[n - 1][0], f[n - 1][1]);
12     }
13 };
复制代码

 

参考资料

  【宫水三叶】状态机 DP 运用题:https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/solution/by-ac_oier-fjhp/

posted @   onlyblues  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示