leetcode バックトラッキング アルゴリズム

バックトラッキングアルゴリズム

1.リートコード77の組み合わせ

//1. leetcode 77 组合
//组合是不强调元素的顺序,排列强调元素的顺序

class Solution {
    
    

private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(int n, int k, int startIndex) {
    
    
        if (path.size() ==  k) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i <= n; i++) {
    
    
            path.push_back(i);  //处理节点
            backtracking(n, k, i + 1);  //递归
            path.pop_back(); // 回溯 撤销处理的节点
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
    
    
        backtracking(n ,k , 1);
        return result;
    }
};

//进行优化

class Solution {
    
    

private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(int n, int k, int startIndex) {
    
    
        if (path.size() ==  k) {
    
    
            result.push_back(path);
            return;
        }
        //优化 进行剪枝
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) {
    
    
            path.push_back(i);  //处理节点
            backtracking(n, k, i + 1);  //递归
            path.pop_back(); // 回溯 撤销处理的节点
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
    
    
        backtracking(n ,k , 1);
        return result;
    }
};

2. Leetcode 216 結合合計 III

//2.leetcode 216 组合总和 III
class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(int targetsum, int k , int sum, int startindex) {
    
    
        //剪枝
        if (sum > targetsum) {
    
    
            return;
        }
        if (path.size() == k) {
    
    
            if (sum == targetsum) result.push_back(path);
            return;
        }
        //优化
        for (int i = startindex;  i <= 9 - (k - path.size()) + 1; i++) {
    
    
            sum += i;
            path.push_back(i);
            backtracking(targetsum, k, sum, i + 1);
            sum -= i;
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
    
    
        backtracking(n, k, 0, 1);
        return result;
    }
};

3. leetcode 電話番号の 17 文字の組み合わせ

//3.leetcode 17 电话号码的字母组合

class Solution {
    
    
private:
    const string letterMap[10] = {
    
    
        "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz",
    };
public:
    vector<string> result;
    string s;
    void backtracking(const string& digits, int index) {
    
    
        if (index == digits.size()) {
    
    
            result.push_back(s);
            return;
        }
        int digit = digits[index] - '0';
        string letters = letterMap[digit];
        for (int i = 0; i < letters.size(); i++) {
    
    
            s.push_back(letters[i]);
            backtracking(digits, index  + 1);
            s.pop_back();
        }
    }
    vector<string> letterCombinations(string digits) {
    
    
        if (digits.size() == 0) {
    
    
            return result;
        }
        backtracking(digits, 0);
        return result;
    }
};

4. leetcode 39の組み合わせ合計

//4.leetcode 39 组合总和


class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startindex) {
    
    
        if (sum > target) return;
        if (sum == target) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = startindex; i < candidates.size(); i++) {
    
    
            sum += candidates[i];
            path.push_back(candidates[i]);
            //使用i 表示可以重复使用当前数
            backtracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    
    
        result.clear();
        path.clear();
        backtracking(candidates, target, 0, 0);
        return result;
    }
};


//优化

class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startindex) {
    
    
        // if (sum > target) return;
        if (sum == target) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = startindex; i < candidates.size() && sum + candidates[i] <= target; i++) {
    
    
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    
    
        result.clear();
        path.clear();
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0);
        return result;
    }
};

5. Leetcode 40 合計 II

//5.leetcode 40. 组合总和 II

class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startindex, vector<bool>& used) {
    
    
        if (sum == target) {
    
    
            result.push_back(path);
            return;
        } 
        for (int i = startindex; i < candidates.size() && sum + candidates[i] <= target; i++) {
    
    
           if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
    
    
               continue;
           }
           sum += candidates[i];
           path.push_back(candidates[i]);
           used[i] = true;
           backtracking(candidates, target, sum, i + 1, used);
           used[i] = false;
           sum -= candidates[i];
           path.pop_back();
       }
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
    
    
        vector<bool> used(candidates.size(), false);
        path.clear();
        result.clear();
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, used);
        return result;
    }
};

6. leetcode 131 分割回文文字列

//6.leetcode 131 分割回文串
class Solution {
    
    
private:
    vector<vector<string>> result;
    vector<string> path;
    void backtracking(const string& s, int startindex) {
    
    
        if (startindex >= s.size()) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = startindex; i < s.size(); i++) {
    
    
            if (isPalindrome(s, startindex, i)) {
    
    
                string str = s.substr(startindex, i - startindex + 1);
                path.push_back(str);
            } else {
    
    
                continue;
            }
            backtracking(s, i + 1);
            path.pop_back();
        }
    }

    bool isPalindrome(const string& s, int start, int end) {
    
    
        for (int i = start, j = end; i < j; i++, j--) {
    
    
            if (s[i] != s[j]) {
    
    
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<string>> partition(string s) {
    
    
        result.clear();
        path.clear();
        backtracking(s, 0);
        return result;
    }
};

7. leetcode 93でIPアドレスを復元する


//7.leetcode 93. 复原 IP 地址
class Solution {
    
    
private:
    vector<string> result;
    //startindex搜索的起始位置 
    void backtracking(string& s, int startindex, int pointnum) {
    
    
        if (pointnum == 3) {
    
      //逗点数量为三时,分割结束
            //判断第四段数字是否合法
            if (isValid(s, startindex, s.size() - 1)) {
    
    
                result.push_back(s);
            }
            return;
        }
        for (int i = startindex; i < s.size(); i++) {
    
    
            if (isValid(s, startindex, i)) {
    
    
                s.insert(s.begin() + i + 1, '.');  //在i之后插入逗点
                pointnum++;
                backtracking(s, i + 2, pointnum);  //下一个字串的起始位置为i + 2
                pointnum--;                   // 回溯
                s.erase(s.begin() + i + 1);  //回溯删除逗点
            } else break;
        }
    }
    bool isValid(const string& s, int start, int end) {
    
    
        if (start > end) {
    
    
            return false;
        }
        //0开头的字符不合法
        if (s[start] == '0' && start != end) {
    
    
            return false;
        }
        int num = 0;
        for (int i = start; i <= end; i++) {
    
    
            //遇到非数字字符不合法
            if (s[i] > '9' || s[i] < '0') {
    
    
                return false;
            }
            num = num * 10 + (s[i] - '0');
            //不能大于255
            if (num > 255) {
    
    
                return false;
            }
        }
        return true;
    }
public:
    vector<string> restoreIpAddresses(string s) {
    
    
        result.clear();
        if (s.size() > 12) return result;  
        backtracking(s, 0, 0);
        return result;
    }
};

8. リートコード 78 サブセット

//8.leetcode 78 子集
class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startindex) {
    
    
        result.push_back(path);
        if (startindex >= nums.size()) {
    
    
            return;
        }
        for (int i = startindex; i < nums.size(); i++) {
    
    
            path.push_back(nums[i]);
            backtracking(nums, i  + 1);
            path.pop_back();
        }
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
    
    
        result.clear();
        path.clear();
        backtracking(nums, 0);
        return result;
    }
};

9. leetcode 491 増加サブシーケンス

//9. leetcode 491 递增子序列
class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startindex) {
    
    
        if (path.size() > 1) {
    
    
            result.push_back(path);
        }
        unordered_set<int> uset;
        for (int i = startindex; i < nums.size(); i++) {
    
    
            if (!path.empty() && nums[i] < path.back() || uset.find(nums[i]) != uset.end()) {
    
    
                continue;
            }
            uset.insert(nums[i]);
            path.push_back(nums[i]);
            backtracking(nums, i + 1);
            path.pop_back();
        }

    }
public:
    vector<vector<int>> findSubsequences(vector<int>& nums) {
    
    
        result.clear();
        path.clear();
        backtracking(nums, 0);
        return result;
    }
};

10. leetcode 46 の完全な置換

//10.leetcode 46 全排列
class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
    
    
        if (path.size() == nums.size()) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
    
    
            if (used[i] == true) continue;
            used[i] = true;
            path.push_back(nums[i]);
            backtracking(nums, used);
            path.pop_back();
            used[i] = false;
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
    
    
        result.clear();
        path.clear();
        vector<bool> used(nums.size(), false);
        backtracking(nums, used);
        return result;

    }
};

11. リートコード47 フルアレンジⅡ

//11.leetcode 47 全排列 II

class Solution {
    
    
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
    
    
        if (path.size() == nums.size()) {
    
    
            result.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
    
    
            if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
    
    
                continue;
            }
            if (used[i] == false) {
    
    
                used[i] = true;
                path.push_back(nums[i]);
                backtracking(nums, used);
                path.pop_back();
                used[i] = false;
            }
        }
    }
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
    
    
        result.clear();
        path.clear();
        sort(nums.begin(), nums.end());
        vector<bool> used(nums.size(), false);
        backtracking(nums,  used);
        return result;
    }
};

12. Leetcode 332 旅程を再調整する

//12. leetcode 332 重新安排行程
class Solution {
    
    
private:
    unordered_map<string, map<string, int>> targets;
    bool backtracking(int ticketNum, vector<string>& result) {
    
    
        if (result.size() == ticketNum + 1) {
    
    
            return true;
        }
        for (pair<const string, int>& target : targets[result[result.size() - 1]]) {
    
    
            //记录飞机是否飞过了
            if (target.second > 0) {
    
    
                result.push_back(target.first);
                target.second--;
                if (backtracking(ticketNum, result)) return true;
                result.pop_back();
                target.second++;
            }
        }
        return false;
    }
public:
    vector<string> findItinerary(vector<vector<string>>& tickets) {
    
    
        targets.clear();
        vector<string> result;
        for (const vector<string>& vec : tickets) {
    
    
            targets[vec[0]][vec[1]]++;
        }
        result.push_back("JFK");
        backtracking(tickets.size(), result);
        return result;    

    }
};

13.リートコード51Nクイーン

//13.leetcode 51 N 皇后

class Solution {
    
    
private:
    vector<vector<string>> result;
    //n为输入的期盼大小
    //row是当前递归到棋牌的第几行了
    void backtracking(int n, int row, vector<string>& chessboard) {
    
    
        if (row == n) {
    
    
            result.push_back(chessboard);
            return;
        }
        for (int col = 0; col < n; col++) {
    
    
            if (isValid(row, col, chessboard, n)) {
    
    
                chessboard[row][col] = 'Q';
                backtracking(n, row + 1, chessboard);
                chessboard[row][col] = '.';
            }
        }
    }
    bool isValid(int row, int col, vector<string>& chessboard, int n) {
    
    
        int count = 0;
        // 检查列
        for (int i = 0; i < row; i++) {
    
    
            if (chessboard[i][col] == 'Q') {
    
    
                return false;
            }
        }
        //检查45度角是否有皇后
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
    
    
            if (chessboard[i][j] == 'Q') {
    
    
                return false;
            }
        }
        //检查135度角是否有皇后
        for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
    
    
            if (chessboard[i][j] == 'Q') {
    
    
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
    
    
        result.clear();
        std::vector<std::string> chessboard(n, std::string(n, '.'));
        backtracking(n, 0, chessboard);
        return result;
    }
};

14. leetcode 37 数独を解く

//14.leetcode 37. 解数独

class Solution {
    
    
private:
    bool backtracking(vector<vector<char>>& board) {
    
    
        for (int i = 0; i < board.size(); i++) {
    
         //遍历行
            for (int j = 0; j < board[0].size(); j++) {
    
      //遍历列
                if (board[i][j] != '.') continue;
                for (char k = '1'; k <= '9'; k++) {
    
          //i,j 这个位置放k是否合适
                    if (isVaild(i, j, k, board)) {
    
    
                        board[i][j] = k;                 //放置k
                        if (backtracking(board)) return true;  //如果找到一组合适的就返回
                        board[i][j] = '.';   //回溯  撤销k
                    }
                }
                return false;          //9个数都试完了 不行 就返回false
            }
        }
        return true;  //遍历结束 没有返回false   则找到了合适的期盼位置
    }
    bool isVaild(int row, int col, char val, vector<vector<char>>& board) {
    
    
        for (int i = 0; i < 9; i++) {
    
        //判断行里是否有重复
            if (board[row][i] == val) {
    
    
                return false;
            }
        }
        for (int j = 0; j < 9; j++) {
    
        //判断列里是否有重复
            if (board[j][col] == val) {
    
    
                return false;
            }
        }
        int startRow = (row / 3) * 3;
        int startCol = (col / 3) * 3;
        //判断九方格里是否有重复
        for (int i = startRow; i < startRow + 3; i++) {
    
    
            for (int j = startCol; j < startCol + 3; j++) {
    
    
                if (board[i][j] == val) {
    
    
                    return false;
                }
            }
        }
        return true;
    }

public:
    void solveSudoku(vector<vector<char>>& board) {
    
    
        backtracking(board);
    }
};

おすすめ

転載: blog.csdn.net/weixin_44847326/article/details/123826735