LeetCode 使序列遞增的最小交換(動態規劃)

2021-09-22 19:53:56 字數 2034 閱讀 8414

我們有兩個長度相等且不為空的整型陣列 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

解釋:

交換 a[3] 和 b[3] 後,兩個陣列如下:

a = [1, 3, 5, 7] , b = [1, 2, 3, 4]

兩個陣列均為嚴格遞增的。

注意:

a, b 兩個陣列的長度總是相等的,且長度的範圍為 [1, 1000]。

a[i], b[i] 均為 [0, 2000]區間內的整數。

思路分

析:\color思路分析:

思路分析

:這道題的確實有點難度,對於分析歸納能力要求挺高的。

剛開始吧,可能大家都想著使用類似貪心策略,就是遇到a[i - 1] >= a[i]這種逆序的時候,我們就將a[i]和b[i]進行交換,這時大家都會被乙個測試示例難倒

0   4   4   5

0 1 6 8

第一次遇到a[i - 1] >= a[i]時,i = 2,按照貪心策略,我們應該交換a[2]和b[2],交換之後我們又發現a[3]出現了逆序,接著有需要交換a[3]和b[3],所以總共需要兩次交換。蛋式這道題只需要交換1次,即我們交換a[1]和b[1]即可同時達到a、b嚴格遞增。因此這種簡單的貪心策略行不通。

經過查閱別人的實現,發現了一種動態規劃的方法。

swapvec[ i ] 表示第 i 個元素進行交換,使a[0, i],b[0,i]嚴格單調遞增的最小交換次數

keepvec[ i ] 表示第 i 個元素不進行交換,使a[0, i],b[0,i]嚴格單調遞增的最小交換次數。

現在的問題就是我們如何找到狀態轉移方程。

(1)如果a[ i ] > a[ i - 1 ] && b[ i ]> b[ i - 1 ],對於這種情況,本身就是遞增的,本不需要進行交換a[i]和b[i]

swapvec[ i ]表示強制交換a[i]、b[i]即交換第i個元素,那麼前乙個位置i-1也要交換,同時交換才能繼續保證同時遞增,所以swapvec[ i ] = swapvec[ i - 1 ]+1

keepvec[ i ]表示不交換a[i]、b[i],即不交換第i個元素,則第i-1個元素也不需要交換,keepvec[ i ]=keepvec[ i - 1 ]

(2)如果a[ i ] > b[ i - 1 ] && b[ i ]> a[ i - 1 ],對於此種情況,必須要交換a[i]、b[i]才能保持遞增

swapvec[i]正好也是要交換當前位置,而前乙個位置不能交換,那麼swapvec[ i ] = keepvec[ i - 1 ] +1

keepvec[ i ]是不能交換當前位置,那麼我們可以通過交換前乙個位置來同樣實現遞增,即keepvec[ i ] = swapvec[ i - 1 ]

如果兩種情況均成立時取較小值。

Leetcode 801 使序列遞增的最小交換次數

回溯搜尋 author niuxy date 2020 7 12 6 41 下午 description 回溯法,暴力搜尋 public int minswap0 int a,int b minswap a,b,0,0 return an int an integer.max value publi...

801 使序列遞增的最小交換次數

我們有兩個長度相等且不為空的整型陣列 a 和 b 我們可以交換 a i 和 b i 的元素。注意這兩個元素在各自的序列中應該處於相同的位置。在交換過一些元素之後,陣列 a 和 b 都應該是嚴格遞增的 陣列嚴格遞增的條件僅為a 0 a 1 a 2 a a.length 1 給定陣列 a 和 b 請返回...

801 使序列遞增的最小交換次數

我們有兩個長度相等且不為空的整型陣列 nums1 和 nums2 在一次操作中,我們可以交換 nums1 i 和 nums2 i 的元素。例如,如果 nums1 1,2,3,8 nums2 5,6,7,4 你可以交換 i 3 處的元素,得到 nums1 1,2,3,4 和 nums2 5,6,7,8...