[刷題]801 Min Swaps To Make Sequences Increasing|C++|LeetCode

 

一、原始想法

(一)概念

原始概念圖

題意為給兩個序列A和B,只能交換同行的AB元素,使得A和B為嚴格遞增序列(A[1]<A[2]...)的最小交換次數。如果A[i-1] < B[i] < A[i+1]且B[i-1] < A[i] < B[i+1]為真,則swap(A[i], B[i])是安全的,因為不會增加更多遞減。

(二)實作

isSafe() 程式碼

isSafe()可以拿來檢查swap(A[i], B[i])是否安全?

主架構 程式碼

只檢查i是否安全是不夠的,因為有可能i-1也是安全的,因此為了要消掉遞增,我們至少就有2種選擇,因此我們需要知道翻轉i-1比較好?還是翻轉i比較好?主架構考慮了4種情境:

  1. pair(i-1, i)和pair(i, i+1)都是遞減的,且i是安全的,翻轉i是比較好的選擇,因為翻轉i可以消掉2個遞增。即使i-1也是安全的,但翻轉i-1只能消掉1個遞減。
  2. i-1是安全的,優先翻轉i-1。
  3. i-1是不安全,但i是安全的,則翻轉i。
  4. i-1和i都是不安全的,則向左向右,搜尋連續不安全的邊界,然後執行最大連續不安全數較少的一方。

最後我的演算法在98 / 117是失敗,顯然我沒有考慮到所有情境。我覺得我沒有處理到連續遞減的情境,這可能是需要再思考的。

二、動態規劃 (Dynamic programming)

(一)概念

動態規劃 概念

上圖左邊為動態規劃的遞迴關係式,這裡使用了兩張表格,分別為swap和notSwap,一開始初始化為別為1和0。遞迴關係式有兩條,會先執行第1條,再執行第2條。

  1. 如果A[i-1] < A[i]且B[i-1] < B[i],則swap[i] = swap[i-1]+1,意思為我翻轉i-1且翻轉i;notSwap[i] = notSwap[i-1],意思為我不翻轉i-1且不翻轉i
  2. 如果A[i-1] < B[i]且B[i-1] < A[i],則swap[i] = min(swap[i], notSwap[i-1]+1),意思為我不翻轉i-1但翻轉i;notSwap[i] = min (swap[i-1], notSwap[i]),意思為我翻轉i-1但不翻轉i。

swap[n] means the minimum swaps to make the A[i] and B[i] sequences increasing for 0 <= i <= n, in condition that we swap A[n] and B[n] notSwap[n] is the same with A[n] and B[n] not swapped.

(二)實作

動態規劃 程式碼

三、相關文章

請詳見LeetCode相關文章

四、參考資料

  1. 801 Min Swaps To Make Sequences Increasing Source code
  2. Lee215. 2018. [Java/C++/Python] DP O(N) Solution. LeetCode

留言