LeetCode每日一题----416分割等和子集

LeetCode每日一题----416分割等和子集

首先我们对题目进行分析,他需要将一个集合划分成两个相等和的集合,那么我们可以确定如下几点:

  1. 列表元素和为偶数 不是偶数的return False
  2. 如果列表中最大的元素大于总的和的一半,那么return False

深度优先DFS方法

我们已经分析出了如上几点,那么我们现在的主要任务就是去找元素的和可以刚好是总和的一半,要是可以找到几个元素的和是总数的一半,那么另一半自然也是总和的一半,这样就符合要求了,自然的我们想到遍历的方法可以是DFS。

对于这种给定的是数组的数据结构进行DFS,我们通常是如下做法:

def dfs(nums,total):
	if total==0:
		return True
	if total<0:
		return False
	for i in range(len(nums-1):
		if dfs(nums[i+1:],total-nums[i]:
			return True
	return False

大家可以记住这样的模板,便于以后的算法练习

但是,我在LeetCode通过这个方法提交,结果
LeetCode每日一题----416分割等和子集_第1张图片
看来递归的方法还是耗时很厉害的

动态规划

当我们在上面分析之后 发现0/1背包问题很类似 我们可以考虑利用动他规划求解

if not nums:
	return True
total = sum(nums)
maxNum = max(nums)
if total & 1:
	return False
target = total // 2
if maxNum > target:
	return False
        
dp = [[0] * (target + 1) for _ in range(n)]
for i in range(n):
	dp[i][0] = True
    dp[0][nums[0]] = True
    for i in range(1, n):
        num = nums[i]
        for j in range(1, target + 1):
            if j >= num:
                dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num]
            else:
                dp[i][j] = dp[i - 1][j]
        
return dp[n - 1][target]


你可能感兴趣的:(LeetCode刷题,leetcode,算法,数据结构,动态规划)