368 最大整除子集

2021-09-26 00:18:00 字數 1386 閱讀 5136

給出乙個由無重複的正整數組成的集合,找出其中最大的整除子集,子集中任意一對 (si,sj) 都要滿足:si % sj = 0 或 sj % si = 0。

如果有多個目標子集,返回其中任何乙個均可。

示例 1:

輸入: [1,2,3]

輸出: [1,2] (當然, [1,3] 也正確)

示例 2:

輸入: [1,2,4,8]

輸出: [1,2,4,8]

思路:較小數對較大數取餘一定為0,那麼問題就變成了看較大數能不能整除這個較小數。如果陣列是無序的,處理起來就比較麻煩,所以我們首先可以先給陣列排序,這樣我們每次就只要看後面的數字能否整除前面的數字。動態規劃解決,額外設定兩個陣列。

1、其中dp[i]表示到數字nums[i]位置最大可整除的子集合的長度。如何求dp[i]?

對於i,遍歷到陣列末尾,如果nums[j]能整除nums[i], 且dp[i] < dp[j] + 1的話,本來數字nums[j]位置最大可整除的子集合的長度為dp[j],而此時nums[j]能整除nums[i],因此,狀態轉移方程為:dp[i] =max(dp[i] , dp[j] + 1)(j>i).因為同乙個數可能存在於好幾個整除子集中,所以我們要遍歷找最大的。

通過這個過程能看出,求dp[i]需要從後往前遍歷,因為求前面的值要用到後面的結果。

2、由於本文需要求出集合的元素,而不僅僅是個數,因此需要第二個陣列parents,其中parents[i]訪問得最大可整除的子集合的前提下,上乙個能整除nums[i]的數字的位置,也就是1中提到的j。最後可以根據parents[i]一點點恢復最大可整除的子集合的元素。

3、兩個整型變數mx和mx_idx分別表示最大子集合的長度和起始數字的位置。最後通過mx_idx找到最大可整除的子集合的第乙個元素,通過parents[i]順次找下去,一共找mx個元素,就構成結果了。

因此,總結一下:我們可以從後往前遍歷陣列,對於某個數字再遍歷到末尾,在這個過程中,如果nums[j]能整除nums[i], 且dp[i] < dp[j] + 1的話,更新dp[i]和parent[i],如果dp[i]大於mx了,還要更新mx和mx_idx。

最後迴圈結束後,我們來填res數字,根據parent陣列來找到每乙個數字。

舉例如下:

}//回溯找到最大的整除子集

for(int i=0; i

return re;}};

368 最大整除子集

給出乙個由無重複的正整數組成的集合,找出其中最大的整除子集,子集中任意一對 si,sj 都要滿足 si sj 0 或 sj si 0。如果有多個目標子集,返回其中任何乙個均可。示例 1 輸入 1,2,3 輸出 1,2 當然,1,3 也正確 示例 2 輸入 1,2,4,8 輸出 1,2,4,8 自己寫...

LeetCode368 最大整除子集

給出乙個由無重複的正整數組成的集合,找出其中最大的整除子集,子集中任意一對 si,sj 都要滿足 si sj 0 或 sj si 0。如果有多個目標子集,返回其中任何乙個均可。示例 1 輸入 1,2,3 輸出 1,2 當然,1,3 也正確 示例 2 輸入 1,2,4,8 輸出 1,2,4,8 然後可...

leetcode 368 最大整除子集

思路 其實和最長上公升子串行的思路基本一致。dp i 表示以nums i 結尾的最大的整數子集。dp i max dp j 1,dp i 其中nums j nums i 0 nums i nums j 0 為了避免6 2 4 這樣的序列出現,只需先對nums進行一下排序即可。需要輸出子集,那麼只要開...