日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

282. Expression Add Operators

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 282. Expression Add Operators 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 題目理解
  • 分析
    • 第一步: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

表達式上一步valuevalue
11
1+211+2=3
1+2+333+3=6

例如計算1-2+3

表達式上一步valuevalue
11
1-211-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為例。

表達式上一步valuevalue
1+211+2=3
1+2*333*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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。