LeetCode || 递归 / 回溯

呜呜呜 递归好不想写qwq

求“所有情况”这种就递归

17. Letter Combinations of a Phone Number

题意:在九宫格上按数字,输出所有可能的字母组合

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路:递归回溯求解

递归保存的是每层的状态,因此每层的 str 不应该改,而是更改str和idx后进入到下一层

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        int n = digits.length();
        if (n == 0) return {};
        vector<string> ans;
        string dict[] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        dfs("", 0, dict, n, digits, ans);
        return ans;
    }
    void dfs(string str, int idx, string dict[], int n, string digits, vector<string> &ans) {
        if (idx == n) {
            ans.push_back(str);
            return;
        }
        if (digits[idx] <= '1' || digits[idx] > '9') return;
        for (int i = 0; i < dict[digits[idx] - '0'].length(); i++) {
            //str += dict[digits[idx] - '0'][i];
            dfs(str + dict[digits[idx] - '0'][i], idx + 1, dict, n, digits, ans);
        }
    }
};
View Code

22. Generate Parentheses

题意:n组括号,求搭配情况数

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

思路:emm递归

 快乐 递归函数里记录每层的状态

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> ans;
        dfs(ans, "", 0, 0, n);
        return ans;
    }
    void dfs(vector<string> &ans, string str, int cnt1, int cnt2, int n) {
        if (cnt1 + cnt2 == n * 2) {
            ans.push_back(str);
            return;
        }
        if (cnt1 < n) dfs(ans, str + '(', cnt1 + 1, cnt2, n);
        if (cnt2 < cnt1) dfs(ans, str + ')', cnt1, cnt2 + 1, n);
    }
};
View Code

37. Sudoku Solver

题意:求解数独

思路:八皇后的思路,在每个'.'的格子里填可能的数字,填好一个往下递归,如果出现这个格子没有可填的就回溯到上一层

呜呜呜

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        dfs(board, 0, 0);
    }
    bool dfs (vector<vector<char>>& board, int row, int col) {
        if (col == 9) {
            row++;
            col = 0;
        }
        if (row == 9) return true;
        if (board[row][col] != '.') {
            return dfs(board, row, col + 1);
        } else {
            for (int i = 1; i <= 9; i++) {
                char x = i + '0';
                if (check(board, row, col, x)) {
                    board[row][col] = x;
                    if (dfs(board, row, col + 1)) return true;
                }
                board[row][col] = '.';
            }
        }
        return false;
    }
    bool check (vector<vector<char>>& board, int row, int col, char val) {
        for (int i = 0; i < 9; i++) {
            if (board[row][i] == val && i != col) {
                return false;
            }
        }
        for (int i = 0; i < 9; i++) {
            if (board[i][col] == val && i != row) {
                return false;
            }
        }
        for (int i = row / 3 * 3; i < row / 3 * 3 + 3; i++) {
            for (int j = col / 3 * 3; j < col / 3 * 3 + 3; j++) {
                if (board[i][j] == val && i != row && j != col) {
                    return false;
                }
            }
        }
        return true;
    }
};
View Code

39. Combination Sum

题意:给出一组无重复的数,在里面任意取数(每个数可以取无数次),使得数字之和为target,求解所有情况

递归中记录(要继续取数的起始位置,当前取过的数,他们的和)

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        dfs(candidates, 0, 0, {}, target, res);
        return res;
    }
    void dfs(vector<int>& candidates, int start, int sum, vector<int> cur, int target, vector<vector<int>>& res) {
        for (int i = start; i < candidates.size(); i++) {
            if (sum + candidates[i] > target) {
                continue;
            } else if (sum + candidates[i] == target) {
                cur.push_back(candidates[i]);
                res.push_back(cur);
                cur.pop_back();
                continue;
            } else {
                cur.push_back(candidates[i]);
                dfs(candidates, i, sum + candidates[i], cur, target, res);
                cur.pop_back();
            }
        }
    }
};
View Code
原文地址:https://www.cnblogs.com/pinkglightning/p/10322241.html