当前位置: 首页 > ai >正文

Leetcode 494. 目标和

Leetcode 494. 目标和 

回溯算法

回溯算法实现,但会出现 超时 的情况。时间复杂度是O(2^n), n表示数组的长度,每个数字有两个状态,因此是2^n。

思路就是构建一个决策树,如下图所示:

  1. 决策树构建:每个数字有两种选择(加或减),形成一个二叉树
  2. 递归探索:深度优先遍历所有可能的组合
  3. 终止条件:当处理完所有数字时,检查当前和是否等于target
  4. 剪枝优化:可以提前终止不可能达到target的分支

Code

class Solution(object):def findTargetSumWays(self, nums, target):""":type nums: List[int]:type target: int:rtype: int"""# @lc code=endself.count = 0self.backtracking(nums, target, 0, 0)return self.countdef backtracking(self, nums, target, index, cur_sum):if index == len(nums):if cur_sum == target:       ### 串联起所有整数,所以是放到这里面来进行退出self.count += 1return self.backtracking(nums, target, index+1, cur_sum + nums[index])self.backtracking(nums, target, index+1, cur_sum - nums[index])

动规算法

思路:

  • 这道题是关键是要将带“+”和“-”的数字进行划分,根据这二者的关系得到一个方程组,根据方程组来得到一个关系
  • 假设left为带“+”的数字总和,right为带"-"的数字总和。(这里的数字都是大于等于0,正负性是由前面的符号决定的,这里是将去除符号后得到的数字)

  • 另外,为什么left + right == sums,是因为题目已经限制了 nums[i] >= 0,因此原数组的每一个数字都是正的
  • 那么有left + right == sums. left - right == target,结合二者得到 left = ( target + sums ) / 2
  • 因此就将关系转换到只要求背包容量为 left == ( target + sums ) /2 下有多少种这样的组合。
  • 另外,若 nums = [1,1,1,1,1,1,1], target = 4, sums = 7 , 此时 ( target + sums ) /2 = 5.5, 那此时就说明了不存在这样的组合来满足题意,因为都是nums里都是整数。
  • 那关系就很清楚了,我们现在只要对数组进行求和,来判断和为 ( target + sums ) /2 下的组合有多少种就行。
  • 求和为某个target下的组合,回溯可以解决。
  • 这道题的dp数组的实现方式就跟“爬楼梯”差不多了,但爬楼梯限定在了距离为1和2,这里的话是根据nums[i]的值

Code

class Solution(object):def findTargetSumWays(self, nums, target):""":type nums: List[int]:type target: int:rtype: int"""### 1. dp数组定义,一维数组,dp[j]表示凑成 left==j 下的组合次数nums_sum = sum(nums)left = (nums_sum + target) // 2         ### 向下取整,转换为int类型if (nums_sum + target) % 2 == 1:return 0if abs(target) > nums_sum:return 0## 1. dp数组定义# dp = [0] * ( nums_sum + 1 )       ### 数组存在多余的部分,直接到left就行了dp = [0] * ( left + 1 )### 2. dp初始化。dp[0] = 1    ### 3. 递推公式.  ### dp[j] += dp[j-nums[i]]### 4. 遍历顺序### 外层从小到大,内层从大到小(表示一个物品只取一次)for i in range(len(nums)):for j in range(len(dp)-1, -1, -1):if j >= nums[i]:        ### 涉及到数组下标的有效值,因此要做判断。当然这个判断也可以嵌入到循环中,这样的话可以节省循环的次数,不过为了逻辑清晰性,这样也行dp[j] += dp[j-nums[i]]      ### 爬楼梯的话 nums = [1,2]### 5. 打印dp数组return dp[left]    

http://www.xdnf.cn/news/15551.html

相关文章:

  • [spring6: @EventListener @TransactionalEventListener ]-源码分析
  • 100201组件拆分_编辑器-react-仿低代码平台项目
  • .NET 8.0 使用 WebSocket
  • Spring之【BeanDefinition】
  • cuda编程笔记(8)--线程束warp
  • 有n棍棍子,棍子i的长度为ai,想要从中选出3根棍子组成周长尽可能长的三角形。请输出最大的周长,若无法组成三角形则输出0。
  • Java List 集合详解:从基础到实战,掌握 Java 列表操作全貌
  • 自定义 django 中间件
  • 深度学习基础 | Softmax 函数原理详解 + Python实现 + 数学公式
  • 前缀和题目:表现良好的最长时间段
  • Leetcode 03 java
  • CKS认证 | Day6 监控、审计和运行时安全 sysdig、falco、审计日志
  • vue3 自定义vant-calendar header/footer/maincontent
  • EXCEL VBA合并当前工作簿的所有工作表sheet
  • Java全栈面试实录:从电商支付到AIGC的深度技术挑战
  • 机器学习:数据清洗与预处理 | Python
  • 控制台输出的JAVA格斗小游戏-面向对象
  • CMake综合学习1: Cmake的模块化设计
  • 我爱学算法之—— 前缀和(下)
  • 【yaml文件格式说明】
  • 18001.QGroundControl操作文档(一)
  • 【测试100问】为什么要做接口测试?
  • 让K线说话!用形态匹配功能透视通达信数据黑洞
  • 【带权的并集查找】 P9235 [蓝桥杯 2023 省 A] 网络稳定性|省选-
  • 小程序性能优化全攻略:提升用户体验的关键策略
  • 每天一个前端小知识 Day 33 - 虚拟列表与长列表性能优化实践(Virtual Scroll)
  • Oracle 关于一些连接故障的总结
  • NumPy 详解
  • 职业发展:把工作“玩”成一场“自我升级”的游戏
  • Web前端性能优化原理与方法