zoukankan      html  css  js  c++  java
  • LeetCode : Different Ways to Add Parentheses

    Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and .
    Example 1
    Input: "2-1-1".
    ((2-1)-1) = 0
    (2-(1-1)) = 2
    Output: [0, 2]
    Example 2
    Input: "2
    3-45"
    (2
    (3-(45))) = -34
    ((2
    3)-(45)) = -14
    ((2
    (3-4))5) = -10
    (2
    ((3-4)5)) = -10
    (((2
    3)-4)*5) = 10
    Output: [-34, -14, -10, -10, 10]

    这题有点类似算24点,不过比算24点得题目应该是简单,先直接使用暴力dfs搜索:

    class Solution {
    private:
        vector<int> operands;
        vector<char> operators;
    public:
        vector<int> diffWaysToCompute(string input) {
            parse(input);
            return dfs(0, operands.size());
        }
        
        vector<int> dfs(int start, int end) {
            vector<int> res;
            if (start >= end) {
                return res;
            }
            if (start + 1 == end) {
                res.push_back(operands[start]);
                return res;
            }
            for (int i=start + 1; i<end; i++) {
                vector<int> left = dfs(start, i);
                vector<int> right= dfs(i, end);
                for (int l : left) {
                    for (int r: right) {
                        res.push_back(cal(operators[i-1], l, r));
                    }
                }
            }
            return res;
        }
        
        int cal(char op, int a, int b) {
            switch(op) {
                case '+': return a+b;
                case '-': return a-b;
                case '/': return a/b;
                case '*': return a*b;
            }
            return 0;
        }
        
        void parse(string& input) {
            int pos = 0;
            int len = input.size();
            int stage = 0;
            for(;;) {
                // skip spaces
                while (pos < len && input[pos] == ' ') {
                    pos++;
                }
                if (pos >= len) {
                    break;
                }
                if (stage == 0) {
                    // stage == 0, to read in a number
                    bool neg = false;
                    if (input[pos] == '-' || input[pos] == '+') {
                        neg = input[pos] == '-';
                        pos++;
                    }
                    if (input[pos] < '0' || input[pos] > '9') {
                        printf("invalid input, operand format error.
    ");
                        break;
                    }
                    int value = 0;
                    while (pos < len && input[pos] >= '0' && input[pos] <= '9') {
                        value = value * 10 + input[pos++] - '0';
                    }
                    if (neg) {
                        value = -value;
                    }
                    operands.push_back(value);
                    stage = 1;
                    continue;
                }
                if (stage == 1) {
                    // stage == 1, to read in an operator
                    char op = input[pos];
                    if (op == '-' || op == '*' || op == '/' || op == '+') {
                        operators.push_back(op);
                        pos++;
                    } else {
                        printf("invalid input, operator format error.
    ");
                        break;
                    }
                    stage = 0;
                    continue;
                }
                printf("invalid parsing stage.
    ");
                break;
            }
            if (operators.size() != operands.size() - 1) {
                printf("invalid input, operands not match with operators.
    ");
            }
        }
    };
    

    这里解析输入的部分使用自己编写的函数,如果允许的话可以使用C++的istringstream类来解析如下:

    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    int main() {
        vector<int> operands;
        vector<char> operators;
        string input = "2-1-1";
        istringstream ss(input + "+");
        int num;
        char op;
        while (ss >> num && ss >> op) {
            operands.push_back(num);
            operators.push_back(op);
        }
        operators.pop_back();
        
        for (int i: operands) {
            cout<<i<<endl;
        }
        
        for (char ch : operators) {
            cout<<ch<<endl;
        }
        
        return 0;
    }
    

    另外一个dp解法:

    class Solution {
    private:
        vector<int> operands;
        vector<char> operators;
    public:
        vector<int> diffWaysToCompute(string input) {
            parse(input);
            int dlen = operands.size();
            vector<vector<vector<int>>> dp(dlen, vector<vector<int>>(dlen));
            
            for (int i=0; i<dlen; i++) {
                for (int j=i; j>=0; j--) {
                    if (i == j) {
                        dp[j][i].push_back(operands[i]);
                        continue;
                    }
                    for (int k = j; k < i; k++) {
                        auto left = dp[j][k];
                        auto right= dp[k + 1][i];
                        for (auto a: left) {
                            for (auto b: right) {
                                dp[j][i].push_back(cal(operators[k], a, b));
                            }
                        }
                    }
                }
            }
            
            return dp[0][dlen - 1];
        }
        // cal & parse function see codes above
    }
    

    这一类的DP递推方式有一般的有些不同

  • 相关阅读:
    微信下载远程图片的公用方法
    微信接口调用
    微信
    post方法
    asp.net pagebase获取缓存的方法
    sql查询最大id
    Controller里写自己需要的Action,参数的名字必须和路由设置的参数名一致

    递归调用
    队列及其应用
  • 原文地址:https://www.cnblogs.com/lailailai/p/4714944.html
Copyright © 2011-2022 走看看