leetcode 282. Expression Add Operators 深度优先遍历DFS + 回溯

来源:互联网 发布:php开发网站 编辑:程序博客网 时间:2024/04/29 17:26

between the digits so they evaluate to the target value.

Examples:
“123”, 6 -> [“1+2+3”, “1*2*3”]
“232”, 8 -> [“2*3+2”, “2+3*2”]
“105”, 5 -> [“1*0+5”,”10-5”]
“00”, 0 -> [“0+0”, “0-0”, “0*0”]
“3456237490”, 9191 -> []

给定一个字符串,求给定的和(DFS+回溯)
本题注意点
1.取数字的时候可能 超过int的范围,用long来处理
2.前导0
3.乘法要记录上次的计算结果并减去
需要这么几个变量,一个是记录上次的计算结果curRes,一个是记录上次被加或者被减的数preNum,一个是当前准备处理的数curNum。当下一轮搜索是加减法时,preNum就是简单换成curNum,当下一轮搜索是乘法时,preNum是preNum乘以curNum。

嗯嗯,就是这么简单与难,所以呢?还得学习。

代码如下:

import java.util.ArrayList;import java.util.List;/* * http://blog.csdn.net/mine_song/article/details/71024333 * 这个需要记住,好好学习吧 * 面对实习工作的压力,你还差很多 * */class Solution {    public List<String> addOperators(String num, int target)     {        List<String> res = new ArrayList<String>();        if (num == null || num.length() == 0)            return res;        calaByIndexDFS(res, "", num, target, 0, 0, 0);        return res;    }    /*     * 这里使用long是考虑到int越界     * */    public void calaByIndexDFS(List<String> res, String calaStr, String num,            int target, int pos, long curRes, long preRes)     {        if(pos==num.length())        {            if(target==curRes)                res.add(calaStr);        }else         {            for(int i=pos;i<num.length();i++)            {                // 得到当前截出的数                // 对于前导为0的数予以排除,pos为第一位                if(i!=pos && num.charAt(pos)=='0')                    return ;                // 处理前导的另一种方法,当前substring长度和curNum长度不等说明有前导0                // 处理前导0的情况比如“105”,5一种结果是1*05                // if (num.substring(pos, i + 1).length() !=                // String.valueOf(curNum).length())                // return;                // 如果不是第一个字母时,可以加运算符,否则只加数字                long curNum=Long.parseLong(num.substring(pos, i+1));                if(pos==0)                    calaByIndexDFS(res, calaStr+curNum, num, target, i+1, curNum, curNum);                else                 {                    calaByIndexDFS(res, calaStr+"+"+curNum, num,                             target, i+1, curRes+curNum, curNum);                    calaByIndexDFS(res, calaStr+"-"+curNum, num,                             target, i+1, curRes-curNum, -curNum);                    // 注意乘法,因为之前加了preNum,本次要减去!                    calaByIndexDFS(res, calaStr+"*"+curNum, num,                             target, i+1, curRes-preRes + preRes*curNum, preRes*curNum);                }            }        }    }}

下面是C++的做法,这一道题十分值得学习,属于典型的DFS深度优先遍历的做法,

代码如下:

#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <string>#include <climits>#include <algorithm>#include <sstream>using namespace std;class Solution {public:    vector<string> res;    vector<string> addOperators(string num, int target)     {        getAll(num,0,target,"",0,0);        return res;    }    void getAll(string num,int pos,int target,string one,long now,long pre)    {        if (pos == num.length())        {            if (now == target)                res.push_back(one);            return;        }        else        {            for (int i = pos; i < num.length(); i++)            {                if (i != pos && num[pos] == '0')                    return;                string aa = num.substr(pos, i - pos + 1);                long a = getLong(aa);                if (pos == 0)                    getAll(num, i + 1, target, aa, a, a);                else                {                    getAll(num, i + 1, target, one+"+"+aa, now+a, a);                    getAll(num, i + 1, target, one+"-"+aa, now-a, -a);                    getAll(num, i + 1, target, one + "*" + aa,                         now - pre + pre*a, pre*a);                }            }        }    }    long getLong(string a)    {        stringstream ss;        ss << a;        long res = 0;        ss >> res;        return res;    }};
原创粉丝点击