leetcode 282. Expression Add Operators 任意添加运算符计算结果 +深度优先遍历DFS

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。

建议和leetcode 95. Unique Binary Search Trees II 递归构造所有可能的搜索二叉树BST + 卡特兰数leetcode 241. Different Ways to Add Parentheses 深度优先遍历DFS + 类似构造所有的二叉搜索树leetcode 241. Different Ways to Add Parentheses 深度优先遍历DFS + 类似构造所有的二叉搜索树 一起学习,因为做法感觉类似

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

代码如下:

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 <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>

using namespace std;


class Solution
{
public:
    vector<string> res;
    vector<string> addOperators(string num, int target) 
    {
        if (num.length() <= 0)
            return res;

        dfs(num, target, 0, 0, 0, "");
        return res;
    }

    void dfs(string num,int target, int index, long now, long pre, string one)
    {
        if (index == num.length())
        {
            if (now == target)
                res.push_back(one);
            return;
        }
        else
        {
            for (int i = index; i < num.length(); i++)
            {
                if (i > index && num[index] == '0')
                    return;
                else
                {
                    long long a = stoll(num.substr(index, i - index + 1));
                    if (index == 0)
                        dfs(num, target, i + 1, a, a, to_string(a));
                    else
                    {
                        dfs(num, target, i + 1, now + a, a, one+"+"+to_string(a));
                        dfs(num, target, i + 1, now - a, -a, one+"-"+to_string(a));
                        dfs(num, target, i + 1, now-pre+pre*a, pre*a, one+"*"+to_string(a));
                    }
                }
            }
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值