力扣698 劃分為k個相等的子集 回溯演算法

2021-10-21 21:56:05 字數 2104 閱讀 5002

給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。

示例:輸入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4

輸出: true

說明: 有可能將其分成 4 個子集(5),(1,4),(2,3),(2,3)等於總和。

引用labuladong大佬的回溯演算法思想.回溯演算法主要分為遞迴和回溯兩部分.該種方式的題離不開選擇向下遞迴的值以及向下遞迴計算失敗後返回將值還原的回溯操作. 在這兩部分中間根據不同的題進行不同的自定義操作,雖然暴力但是很容易理解,且處理得當也很快.

該題以桶為回溯核心,總耗時1ms oj了該題.強烈推薦labuladong大佬的演算法文章

// return numstodo(target, k, nums);

// 以桶為回溯目標的方法

return buckettodo(target, k, nums);

}

static boolean numstodo(int target, int k, int nums)

//定義乙個桶

int bucket = new int[k];

return bucktrackbynum(target, bucket, 0, nums);

}static boolean buckettodo(int target, int k, int nums)

/** * 以整數陣列為回溯目標,每次回溯找到第乙個能放入的桶中(小於等於目標值,因為向下遞迴的時候並不知道那個桶已經滿了,所以每次需要從頭遞迴桶)

* 然後接著下乙個整數找桶放.當數字完了檢視每個桶是否和目標值一致

* @return

*/static boolean bucktrackbynum(int target, int bucket, int numindex, int nums)

}return true;

}for(int i=0; itarget) continue;

// 如果值小於等於目標值則將桶的值更新並遞迴至下乙個數字

bucket[i] = sum;

//總會遞迴到整數陣列結尾/沒有合適的結果結尾,從結尾開始回歸結果,如果都是true則繼續向上級返回true.否則回溯進行下乙個桶嘗試

if(bucktrackbynum(target, bucket, numindex+1, nums))

// 回溯演算法中將值恢復是很重要的步驟.恢復之前的狀態換乙個新的分支再次嘗試執行

bucket[i] = sum - nums[numindex];

}return false;

}/**

* 以桶為回溯目標,則每次執行以將乙個桶填滿為目的,記錄好當前使用的陣列.

* 乙個桶滿後則開始下乙個桶裝填(以回溯的方式裝填),如果下乙個桶裝填無效則回溯至該桶,切換其他元素嘗試.如果均無果則返回false

* @return

*/static boolean buckettrackbybucket(int target, int k, int bucketnum, int numsindex, int nums, boolean used)

// 執行判斷,判斷是否可以進行下乙個桶的遞迴.

if(bucketnum == target)

// 從該桶上上個執行過的方法中的索引繼續

for(int i=numsindex; itarget) continue;

used[i] = true;

bucketnum = sum;

// 當前桶滿了就去下乙個桶繼續裝填,

if(buckettrackbybucket(target, k, bucketnum, i+1, nums, used))

// false從任意一級失敗都可能返回,失敗則返回false.這時進行引數值回溯再迴圈遞迴嘗試其他數字分支

used[i] = false;

bucketnum = sum - nums[i];

}// 在最後返回的都是遍歷完都沒找到合適數字的,一定是false

return false;

}

698 劃分為k個相等的子集 python

給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。示例 1 輸入 nums 4,3,2,3,5,2,1 k 4 輸出 true 說明 有可能將其分成 4 個子集 5 1,4 2,3 2,3 等於總和。注意 1 k len nums 16 0 n...

(DFS)698 劃分為k個相等的子集

給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。示例 1 輸入 nums 4,3,2,3,5,2,1 k 4 輸出 true 說明 有可能將其分成 4 個子集 5 1,4 2,3 2,3 等於總和。注意 1 k len nums 16 0 n...

力扣 劃分為k個相等的子集

首先是題意 做每道演算法題,最重要的是,讀懂題意,從分析我們可以得出來的是,目標值及每個子集的和target sum nums k,所以就確定了目標值target。得出目標值後,我們可以得到一些一定為false的情況,如 目標值不為整數 nums中有值大於target的 我們還可以先找出nums中是...