目录

  • 题目理解
  • 分析
    • 第一步:dfs获得所有表达式
    • 第二步:计算结果
    • 先计算加减法
    • 计算乘法
    • 时间复杂度
    • 进一步优化

题目理解

输入:一个字符串num,一个int target。输入num只包含数字。
规则:可以给num中包含的数字之间任务添加二目运算符:+ - *,使得表达式的值等于target。
输出:所有可能的符合条件的表达式。

示例1:num=“123”, target=6
输出:[“1+2+3”, “123”]

示例2:num=“232”, target=8
输出:[“23+2", "2+32”]

示例3:num = “105”, target = 5
输出: [“1*0+5”,“10-5”]

分析

从示例中可以看到我们可以在每一个数字之间加运算符,而数字可以是一位数字1、2、3,也可以是两位、三位数字:12、32、123。那么我们可以把1和2连在一起认为是第四种操作。

这道题目看了官方的解答和花花酱的视频,依然云里雾里。一直到看了windliang的解法终于想明白了 。

解题思路是回溯法。每次添加一个操作符和一个数字。以num=123为例。下图是部分递归树。每条路径可以获得一个表达式。

第一步:dfs获得所有表达式

第一步我们使用dfs遍历打印出所有可能的表达式。注意第一个数字比较特别,只加数字,不加操作符。

class Solution {private String num;private int target;public List<String> addOperators(String num, int target) {this.num = num;this.target  = target;dfs(0,"");return null;}private void dfs(int start,String expr){if(start == num.length()){System.out.println(expr);return;}for(int  i = start ;i<num.length();i++){String t = num.substring(start,i+1);if(start == 0){dfs(i+1,t);}else{dfs(i+1,expr+"+"+t);dfs(i+1,expr+"-"+t);dfs(i+1,expr+"*"+t);}}}
}

使用num='123’做测试,得到输出1+2+3 1+2-3 1+2*3 1-2+3 1-2-3 1-2*3 1*2+3 1*2-3 1*2*3 1+23 1-23 1*23 12+3 12-3 12*3 123

第二步:计算结果

有了表达式,可以在每次表达式变化的时候计算表达式的结果。运算包括加法、减法、乘法。因为乘法优先级高,最后再处理。我们先看看怎么计算加减法。

先计算加减法

我们在上面递归树的每个节点加一个结果dfs(n,expr,value)。每个节点在计算表达式的值的时候,需要拿上一个表达式的结果与当前数字n做操作。

例如计算1+2+3

表达式 上一步value value
1 1
1+2 1 1+2=3
1+2+3 3 3+3=6

例如计算1-2+3

表达式 上一步value value
1 1
1-2 1 1-2=-1
1-2+3 -1 -1+3=2

在计算加减法的时候,只需要保存上一步的表达式的值即可。

class Solution {private String num;private int target;private List<String> result;public List<String> addOperators(String num, int target) {this.num = num;this.target  = target;result = new ArrayList<String>();dfs(0,"",0);return result;}private void dfs(int start,String expr,long value){if(start == num.length()){System.out.println(expr+" "+value);if(value == target){}return;}for(int  i = start ;i<num.length();i++){String t = num.substring(start,i+1);long n = Long.parseLong(t);if(start == 0){dfs(i+1,t,n);}else{dfs(i+1,expr+"+"+t,value+n);dfs(i+1,expr+"-"+t,value-n);dfs(i+1,expr+"*"+t,value*n);}}}
}

查看打印结果:1+2+3=6 1+2-3=0 1+2*3=9能够发现加法减法是正确的,乘法计算错了。

计算乘法

以1+2*3为例。

表达式 上一步value value
1+2 1 1+2=3
1+2*3 3 3*3=9

这是计算过程。我们不应该先算加法。我们需要记录下上一步的操作数preOperand,先在结果中减去preOperand。然后preOperand在乘以当前数字。即:val-preOperand + preOperand*n=3-2+2x3=7。计算结果正确。

如果上一步是减法,和上面的过程类似。例如1-2*3。preOperand = 3,val = -1。计算:-1-(-2)+(-2)*3=-5。

如果上一步是减法。例如543。preOperand = 5x4=20,val = 20。计算:20-20+20*3 = 60。也就是说上一步乘法的操作数preOperand = 5x4=20。这样公式就统一了。

至此解答完毕。

class Solution {private String num;private int target;private List<String> result;public List<String> addOperators(String num, int target) {this.num = num;this.target  = target;result = new ArrayList<String>();dfs(0,"",0,0);return result;}private void dfs(int start,String expr,long value,long preOperand){if(start == num.length()){//System.out.println(expr+" "+value);if(value == target){result.add(expr);}return;}for(int  i = start ;i<num.length();i++){String t = num.substring(start,i+1);if(t.charAt(0)=='0' && i>start) break;long n = Long.parseLong(t);if(n > Integer.MAX_VALUE) break;if(start == 0){dfs(i+1,t,n,n);}else{dfs(i+1,expr+"+"+t,value+n,n);dfs(i+1,expr+"-"+t,value-n,-n);dfs(i+1,expr+"*"+t,value-preOperand+preOperand*n,preOperand*n);}}}
}

时间复杂度

在字符串的两个数字之间有4种操作。n个字符串有n-1个空格,所以时间复杂度是O(4n−1)O(4^{n-1})O(4n−1)。

进一步优化

在计算 表达式expr,每次有字符串相加操作。可以使用StringBuilder。可以加快速度。链接。

282. Expression Add Operators相关推荐

  1. leetcode 282. Expression Add Operators | 282. 给表达式添加运算符(中缀表达式求值)

    题目 https://leetcode.com/problems/expression-add-operators/description/ 题解 中缀表达式求值问题,参考:leetcode 227. ...

  2. LintCode 653: Expression Add Operators

    Expression Add Operators Given a string that contains only digits 0-9 and a target value, return all ...

  3. Leetcode重点250题

    LeetCode重点250题 这个重点题目是把LeetCode前400题进行精简.精简方法如下: 删除不常考,面试低频出现题目 删除重复代码题目(例:链表反转206题,代码在234题出现过) 删除过于 ...

  4. LEETCODE-刷题个人笔记 Python(1-400)-TAG标签版本

    1. Array (1) 27. Remove Element(Easy) 给定数组nums和值val,在适当位置删除该值的所有实例并返回新长度. 思路: 不需要使用排序,如果等于该值,则将n-1的值 ...

  5. 寒假LeetCode打卡

    文章目录 @[toc] 链表专题 LeetCode 19. Remove Nth Node From End of List LeetCode 83. Remove Duplicates from S ...

  6. LeetCode All in One 题目讲解汇总(持续更新中...)

    原文地址:https://www.cnblogs.com/grandyang/p/4606334.html 终于将LeetCode的大部分题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开 ...

  7. LinkedIn TAG

    1 [leetcode]243. Shortest Word Distance最短单词距离 Two Pointers 2 [leetcode]244. Shortest Word Distance I ...

  8. taoqick 搜索自己CSDN博客

    L1 L2正则化和优化器的weight_decay参数 kaiming初始化的推导 Pytorch动态计算图 Pytorch自动微分机制 PyTorch中在反向传播前为什么要手动将梯度清零? 通俗讲解 ...

  9. Leet 题目整理归类 - 快速通道 (持续更新)

    刷Leet 5个月了,先总结一下,这里算是每题的快速通道.自己做个记录便于以后重温算法.如果能帮到别人就更好了. 本人是算法新手,如果对于一些题目读者有更好的实现方法,如能不吝赐教,万分感谢. [DF ...

最新文章

  1. ERP成分简介--听觉感觉反应
  2. 快速排序算法的实现 随机生成区间里的数 O(n)找第k小 O(nlogk)找前k大...
  3. SAP Spartacus Org unit detail实例的单例特性
  4. 600W个微信红包封面,人人都能领取到!!!
  5. java私有表示标识_java里面的标识符、关键字和类型
  6. Log4j2进阶使用(Pattern Layout详细设置)
  7. 水晶报表 mysql_水晶报表CrystalReport2008使用JDBC连接MySQL数据库-详细步骤
  8. linux系统运行application,[分享]分享曾经做过的一个嵌入式系统application框架 | 勤奋的小青蛙...
  9. sklearn学习笔记之preprocessing
  10. AppFabric 使用
  11. php mysql日程管理_9.3 日程表数据库设计
  12. 视觉transformer图片处理思路
  13. 无线桥接后无法访问服务器,无线桥接后不能登录副路由器ip地址的解决方法
  14. 手机屏幕常见故障_触屏不灵敏、断触怎么回事?手机触摸屏的基本原理与常见问题排查方法介绍...
  15. mac系统上运行c语言文件
  16. IPA包重签企业证书
  17. 以太网传输中的NNI与UNI
  18. 如何加密html文件怎么打开,文件加密巧用IE浏览器
  19. 2021上半年程序员新书大盘点
  20. 02 nRF52832芯片简介

热门文章

  1. 如何在Linux下安装nginx
  2. [MOSS开发]:如何使用用户控件
  3. WebSocket 实现前后端通信的笔记
  4. ScrollView嵌套ViewPager,ViewPage动态设置高度,嵌套事件冲突——滑动冲突解决方法
  5. 错误记录--更改tomcat端口号方法,Several ports (8005, 8080, 8009)
  6. Android侧滑删除-RecyclerView轻松实现高效的侧滑菜单
  7. Android recycleview实现混合itemview,以及recycleview添加头部尾部
  8. Python四大金刚之四:集合
  9. android 音量调节 seekbar,Android 使用SeekBar调节系统音量
  10. docker php示例,Docker PHP 例子