上述的讨论是建立在 i > 0 的基础上的,而当 i = 0 时,无论是否交换都为合法状态,即可以初始化 dp}[0][0] = 0,dp}[0][1] = 1。又因为求解每一个状态都只与前一个状态有关,所以我们可以用「滚动数组」的方法来进行空间优化。
代码
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defminSwap(self, nums1: List[int], nums2: List[int]) -> int: n = len(nums1) a, b = 0, 1 for i inrange(1, n): at, bt = a, b a = b = n if nums1[i] > nums1[i - 1] and nums2[i] > nums2[i - 1]: a = min(a, at) b = min(b, bt + 1) if nums1[i] > nums2[i - 1] and nums2[i] > nums1[i - 1]: a = min(a, bt) b = min(b, at + 1) returnmin(a, b)
classSolution { public: intminSwap(vector<int>& nums1, vector<int>& nums2){ int n = nums1.size(); int a = 0, b = 1; for (int i = 1; i < n; i++) { int at = a, bt = b; a = b = n; if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) { a = min(a, at); b = min(b, bt + 1); } if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) { a = min(a, bt); b = min(b, at + 1); } } returnmin(a, b); } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { publicintminSwap(int[] nums1, int[] nums2) { intn= nums1.length; inta=0, b = 1; for (inti=1; i < n; i++) { intat= a, bt = b; a = b = n; if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) { a = Math.min(a, at); b = Math.min(b, bt + 1); } if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) { a = Math.min(a, bt); b = Math.min(b, at + 1); } } return Math.min(a, b); } }
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicclassSolution { publicintMinSwap(int[] nums1, int[] nums2) { int n = nums1.Length; int a = 0, b = 1; for (int i = 1; i < n; i++) { int at = a, bt = b; a = b = n; if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) { a = Math.Min(a, at); b = Math.Min(b, bt + 1); } if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) { a = Math.Min(a, bt); b = Math.Min(b, at + 1); } } return Math.Min(a, b); } }
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#define MIN(a, b) ((a) < (b) ? (a) : (b))
intminSwap(int* nums1, int nums1Size, int* nums2, int nums2Size){ int n = nums1Size; int a = 0, b = 1; for (int i = 1; i < n; i++) { int at = a, bt = b; a = n, b = n; if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) { a = MIN(a, at); b = MIN(b, bt + 1); } if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) { a = MIN(a, bt); b = MIN(b, at + 1); } } return MIN(a, b); }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var minSwap = function(nums1, nums2) { const n = nums1.length; let a = 0, b = 1; for (let i = 1; i < n; i++) { let at = a, bt = b; a = b = n; if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) { a = Math.min(a, at); b = Math.min(b, bt + 1); } if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) { a = Math.min(a, bt); b = Math.min(b, at + 1); } } returnMath.min(a, b); };
funcminSwap(nums1, nums2 []int)int { n := len(nums1) a, b := 0, 1 for i := 1; i < n; i++ { at, bt := a, b a, b = n, n if nums1[i] > nums1[i-1] && nums2[i] > nums2[i-1] { a = min(a, at) b = min(b, bt+1) } if nums1[i] > nums2[i-1] && nums2[i] > nums1[i-1] { a = min(a, bt) b = min(b, at+1) } } return min(a, b) }
funcmin(a, b int)int { if a > b { return b } return a }
复杂度分析
时间复杂度:O(n),其中 n 为数组 nums}_1 和 nums}_2 的长度。需要遍历两个数组一次,每个状态的计算时间是 O(1)。