暴力解法:
public記憶化遞迴:final
boolean canpartition1(int
nums)
//剪枝
int sum = 0;
int max = 0;
for (int i = 0; i < nums.length; i++)
if (sum % 2 != 0)
int target = sum / 2;
if (max >target)
if (max ==target)
//回溯遍歷
return
hassubarray(nums, target);
}public
final
boolean hassubarray(int nums, int
target)
if (target == 0)
boolean re = false
;
for (int i = 0; i < nums.length; i++)
int numi =nums[i];
nums[i] = -1;
re = hassubarray(nums, target -numi);
if (re == true
) nums[i] =numi;
}return
false
; }
/*** @author niuxy
* @date 2020/6/29 9:05 下午
* @description 上述回溯思路中,之所以需要回溯是因為每次遞迴呼叫都是在 nums 陣列中選擇了乙個元素
* 該元素不能被後續選擇
* 如果我們要找連續的子陣列,可以將思路逆轉一下
* 變選擇某元素為不選擇某元素,將陣列分割為兩個連續的部分,嘗試所有連續的組合
* 這樣就不必再進行回溯處理,因為沒有選擇某元素
* 但是本題要求的子陣列是不連續的,可以跳著選元素
* 將整體分割為兩個整體後,每個整體可以承擔 target 的任意部分,這使得遍歷所有可能變得很困難
* 用多個子問題的解表示問題的解行不通,嘗試用單個子問題的解表示問題的解
* 用上面的暴力解法,沒有找到子問題的重複結構
* 每次從整體中隨機抽取乙個元素,遍歷所有可能的組合
* 將視角從整體轉到個體,每個個體都有兩種可能,選擇和不選擇
* 遍歷每個個體的所有可能,並求它們的笛卡爾積,也可以遍歷整個解空間,並且可以逐個有序的遍歷元素
*/public
boolean dp(int nums, int n, int target, mapcache)
int key = n * 23 + target * 131071;
if(cache.containskey(key))
boolean re = dp(nums, n - 1, target, cache) || dp(nums, n - 1, target -nums[n], cache);
cache.put(key, re);
return
re; }
public
final
boolean canpartition(int
nums)
int sum = 0;
int max = 0;
for (int i = 0; i < nums.length; i++)
if (sum % 2 != 0)
int target = sum / 2;
if (max >target)
if (max ==target)
//to-do
mapcache = new hashmap();
return dp(nums, nums.length - 1, target, cache);
}
leetcode 416 分割等和子集
方法一 用動態規劃 class solution return res half 方法二 利用遞迴,dfs 此方法較動態規劃要好很多 基本思想 舉例子說明最容易理解,例如 nums 1,5,4,3,7 第一步 對陣列進行排序,nums 1,3,4,5,7 求出其和的一半 half 10 對於陣列中元...
LeetCode416 分割等和子集
主要的思想 於0 1揹包問題,解決方法是動態規劃。我們可以想到,把陣列分割成兩份,並且和相等,那麼每乙份的和是總和的一半。那麼問題就可以轉化為找到一組數,使得他們的和逼近sum 2,最後判斷最大的和是否等於sum 2,如果是則說明存在這樣的組合,也就是存在子集。其和為sum 2,當然了另乙個集合的和...
LeetCode416 分割等和子集
題目 給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。注意 每個陣列中的元素不會超過 100 陣列的大小不會超過 200 示例 1 輸入 1,5,11,5 輸出 true 解釋 陣列可以分割成 1,5,5 和 11 示例 2 輸入 1,2,3,5 輸出 f...