LeetCode 416 python 一维数组动态规划
一维数组动态规划题目要求将数组分为两个相等子集的和,那么如果为真,那么这个数组的总和必定是偶数(条件一),且该数组的最大值必不大于该数组和的一半(条件二)。那么该问题即可转化为求解和为是否有和为total = sum(nums) // 2的子数组问题。使用一维数组dp = [False] * (total+1),边界条件:当和为0时,必为真,则dp[0] = True例:求解和为i (i = (1
一维数组动态规划
题目要求将数组分为两个相等子集的和,那么如果为真,那么这个数组的总和必定是偶数(条件一),且该数组的最大值必不大于该数组和的一半(条件二)。
那么该问题即可转化为求解和为是否有和为total = sum(nums) // 2的子数组问题。
使用一维数组dp = [False] * (total+1),
边界条件:当和为0时,必为真,则dp[0] = True
例:求解和为i (i = (1,2,…total)),
首先遍历每个num in nums,且,为防止重复,i必须逆序遍历。状态转移方程为:当i >= num: dp[i] = dp[i] | dp[i-num]
状态转移方程的意思是:是否有和为i的子数组取决于之前i的状态与i-num的状态。
为何要逆序:
例:[1,2,3,6],dp = [True, False, False, False, False,False, False]
那么遍历完num=1时,若i不逆序,则当i=1时,dp[i] = True(因为dp[i-num] = True),而当i=2时,dp[i] = True,因为dp[i-num] = True(此时i= 2, 因此i-num=1, 而刚更新过的dp[1] = True)。因此i必须逆序,则,较小的和就不会影响较大的和。
为何状态转移方程dp[i] = dp[i] | dp[i-num],
当遍历num in nums时,有可能会出现dp[i-num] = False的情况,然而当前的状态不应该影响以前的状态,若之前遍历的时候dp[i] = True,则若不加 |dp[i],则会出错。
class Solution:
def canPartition(self, nums: List[int]) -> bool:
if sum(nums) % 2 == 1: # 条件一
return False
n = sum(nums) // 2
if max(nums) > n: # 条件二
return False
dp = [False] * (n+1)
dp[0] = True # 初始值
for num in nums:
for i in range(n, 0, -1):
if i >= num:
dp[i] = dp[i-num] | dp[i] # 状态转移方程
return dp[n]

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)