題目連結:
題目意譯:
你被給定一個二維整數陣列 envelopes 其中 envelopes[i] = [wi, hi] 代表一個信封的寬度與高度。
一個信封可以容納進另一個信封中若且唯若該信封的寬度和高度大於另一個寬度和高度。
回傳你可以進行俄羅斯套娃的最大信封數(即,將一個信封放入另一個之中)。
注: 你不得旋轉任何信封。
限制:
1 ≦ envelopes.length ≦ 10 ^ 5
envelopes[i].length == 2
1 ≦ wi, hi ≦ 10 ^ 5
範例測資:
範例 1:
輸入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
輸出: 3
解釋: 你可以進行俄羅斯套娃的最大信封數為 3([2,3] => [5,4] => [6,7])。
範例 2:
輸入: envelopes = [[1,1],[1,1],[1,1]]
輸出: 1
解題思維:
首先我們把每一個信封先按照寬度由小到大排,寬度一樣再由大到小排。
排序後我們可以看到現在 envelopes 中每個信封的寬度都不小於前一個,因此寬度的資訊變得基本上不重要了。
所以刪掉寬度這個資訊後剩下的數字就可以利用經典的最長遞增子序列(Longest Increasing Subsequence,LIS)的解法來解(參見
這題)。
那為什麼一開始要把同樣寬度的信封按高度由大排到小,不能直接取小的或是按由小排到大嗎?
首先,直接取小的會是錯的(看範例 1 就知道了,不能只留下 [6,4]),因為你不知道實際上留哪個高度值才是正解(或不影響正解)。例如說最小的寬度的那幾個信封留最小的高度的那一個會是最好的選擇。
而要把高度值由大排到小是因為「未來」可能把先前挑的取代掉,也就是有可能可以塞得進更多更大的信封之中(參見 LIS 的二分搜尋法之精神)。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。