leetcode中回溯题集合

16 篇文章 0 订阅
12 篇文章 0 订阅

77.Combinations
思路:终止和收敛条件是判断out中的个数达到k。图解请详见博客题解

  vector<vector<int>> combine(int n, int k) {

        vector<int> out;
        vector<vector<int>> res;
        if (k < 1 || n < 1 || n < k)
            return res;
        DFS(n,k,out,res,1);
        return res;

    }
    void DFS(int n,int k,vector<int>& out,vector<vector<int>>& res,int start) {
        if (out.size() == k) {
            res.push_back(out);
        }

        else {
            for (int i = start; i <= n; i++) {
                out.push_back(i);
                DFS(n,k,out,res,i+1);
                out.pop_back();
            }
        }
    }

78.SubsetsSubsets
思路:用到DFS,但是和以往只需要保存叶子节点数据不同,这个需要把路径上所有节点都保存。可能是最新题,竟然是最快的一种。。。。。

 vector<vector<int>> subsets(vector<int>& nums) {
        vector<int> out;
        vector<vector<int>> res;
        res.push_back(out);
        DFS(nums,res,out,0);
        return res;
    }
    void DFS(vector<int>& nums,vector<vector<int>>& res,vector<int>& out,int start) {
        for (int i = start; i < nums.size(); i++) {
            out.push_back(nums[i]);
            res.push_back(out);
            DFS(nums,res,out,i+1);
            out.pop_back();
        }
    }

89.Gray Code
思路1:百度一下二进制数——>格雷码的转换,就知道怎么做了。就是一个数n的每一位和上一位进行异或运算。

vector<int> grayCode(int n) { 
//         这道题如果用二进制转换成格雷码,只要知道转换规则,很容易Gi = Bi xor Bi+1
        vector<int> res;
        for (int i = 0; i < pow(2,n); i++) {
            res.push_back((i>>1) ^ i);
        }
        return res;


    }

思路2:但是如果不知道怎么办,怎么用回溯法呢。

93.Restore IP Addresses
思路:必须走到底才能知道是不是符合要求,用DFS。

vector<string> restoreIpAddresses(string s) {
        vector<string> out;
        vector<string> res;
        DFS(s,0,out,res);
        return res;
    }
    void DFS(string s,int start,vector<string>& out,vector<string>& res) {

        if (start == s.size() && out.size() == 4) {
            string ip = out[0] + "." + out[1] +"." + out[2] + "." + out[3];
            res.push_back(ip);
            return;
        }
        if (s.size() - start > (4 - out.size()) * 3 || s.size() - start < (4 - out.size())) {
            return;
        }

        for (int i = start; i < start + 3 && i < s.size(); i++) {
            string temp = s.substr(start,i - start + 1);
            if (isValid(temp)) {
                out.push_back(temp);
                DFS(s,i + 1,out,res);
                out.pop_back();
            }
        }

    }

    bool isValid(string s) {
        int num = stoi(s);
        if (num < 0 || num > 255)
            return false;
        if (s[0] == '0')
            return s.size() == 1;
        return true;
    }

216.Combination Sum III
思路:

vector<vector<int>> combinationSum3(int k, int n) {
        vector<int> input = {1,2,3,4,5,6,7,8,9};
        vector<int> out;
        vector<vector<int>> res;
        DFS(k,n,0,0,input,out,res);
        return res;
    }
    void DFS(int k,int n,int level,int start,vector<int>& input,vector<int>& out,vector<vector<int>>& res) {
        if (level == k) {
            if (accumulate(out.begin(),out.end(),0) == n)
                res.push_back(out);
            else
                return;
        }
        else {
            for (int i = start; i < input.size(); i++) {
                out.push_back(input[i]);
                DFS(k,n,level+1,i+1,input,out,res);
                out.pop_back();
            }
        }
    }

解法2:

vector<vector<int>> combinationSum3(int k, int n) {
        //vector<int> input = {1,2,3,4,5,6,7,8,9};
        vector<int> out;
        vector<vector<int>> res;
        DFS(k,n,1,out,res);
        return res;
    }
    void DFS(int k,int n,int start,vector<int>& out,vector<vector<int>>& res) {
        if (out.size() == k) {
            if (n == 0)
                res.push_back(out);
            else
                return;
        }

        if (out.size() < k) {
            for (int i = start; i <= 9;i++) {
                out.push_back(i);
                DFS(k,n - i,i+1,out,res);
                out.pop_back();
            }
        }

    }
  1. Subsets II
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<int> out;
        vector<vector<int>> res;
        res.push_back(out);
        DFS(nums,res,out,0);
        return res;
    }
    void DFS(vector<int>& nums,vector<vector<int>>& res,vector<int>& out,int start) {
        for (int i = start; i < nums.size();i++) {
            if (i > start && nums[i] == nums[i-1])
                continue;
            out.push_back(nums[i]);
            res.push_back(out);
            DFS(nums,res,out,i+1);
            out.pop_back();
        }
    }
  1. Palindrome Partitioning
    思路:
vector<vector<string>> partition(string s) {
        vector<vector<string>> res;
        vector<string> out;
        DFS(s,out,res,0);
        return res;
    }

    void DFS(string& s,vector<string>& out,vector<vector<string>>& res,int start) {
        if (start == s.size())
            res.push_back(out);

        for (int i = start; i < s.size(); i++) {
            string temp = s.substr(start,i-start+1);
            if (isValid(temp)) {
                out.push_back(temp);
                DFS(s,out,res,i+1);
                out.pop_back();
            }
        }
    }

    bool isValid(string s) {
        if (s.empty())
            return false;
        int start = 0,end = s.size() - 1;
        while (start < end && s[start] == s[end]) {
            start++;
            end--;
        }
        if (start >= end)
            return true;
        return false;
    }
  1. Letter Case Permutation
    思路1:不用DFS,我们关心的是字母,数字的处理很简单,直接加上就可以了。比如说S = “abc”,那么先让 res = [“”],然后res中的每个字符串分别加上第一个字符a和A,得到 [“a”, “A”],然后res中的每个字符串分别加上第二个字符b和B,得到 [“ab”, “Ab”, “aB”, “AB”],然后res中的每个字符串分别加上第三个字符c和C,得到 [“abc”, “Abc”, “aBc”, “ABc”, “abC”, “AbC”, “aBC”, “ABC”]
vector<string> letterCasePermutation(string S) {
        vector<string> res{""};
        for (char c : S) {
            int len = res.size();
            if (c >= '0' && c <= '9') { //如果是数字,res中每个string加就可以
                for (int i = 0; i < len; i++) {
                    res[i] += c;
                }
            }
            else { //如果是字母,则进行大小写相加
                for (int i = 0; i < len; i++) {
                    res.push_back(res[i]);
                    res[i] += tolower(c);
                    res[len+i] += toupper(c);
                }
            }
        }
        return res;
    }
  1. Beautiful Arrangement
    思路:
int countArrangement(int N) {
        int count = 0;
        vector<bool> visited(N,false);
        DFS(N,1,visited,count);
        return count;
    }
    void DFS(int N,int pos,vector<bool>& visited,int& count) {
        if (pos > N)
            count++;
        for (int i = 1; i <= N; i++) {
           if (!visited[i-1] && isValid(i,pos)) {
                visited[i-1] = true;
                DFS(N,pos+1,visited,count);
                visited[i-1] = false;
            }
        }

    }

    bool isValid(int n,int pos) {
        if (n % pos == 0 || pos % n == 0)
            return true;
        return false;
    }
  1. N-Queens
    思路:终于遇到了经典的N皇后问题,典型的回溯。
vector<vector<string>> solveNQueens(int n) {
        vector<int> C(n,-1);
        vector<vector<string>> res;
        DFS(C,res,0);
        return res;

    }

    void DFS(vector<int>& C,vector<vector<string>>& res,int row) {
        int n = C.size();
        if (row == n) {
            vector<string> out;
            for (int i = 0; i < n; i++) {
                string temp(n,'.');
                temp[C[i]] = 'Q';
                out.push_back(temp);
            }
            res.push_back(out);
        }

        for (int j = 0; j < n; j++) {
            if (isValid(C,row,j)) {
                C[row] = j;
                DFS(C,res,row+1);
                C[row] = -1;
            }
        }
    }


    bool isValid(vector<int> C,int row,int col) {
        for(int i = 0; i < row; i++) {
            if (C[i] == col || abs(row-i) == abs(col-C[i]))
                return false;
        }
        return true;
    }
  1. N-Queens II
int totalNQueens(int n) {
        vector<int> C(n,-1);
        int count = 0;
        DFS(C,count,0);
        return count;
    }
    void DFS(vector<int>& C,int& count,int row) {
        int n = C.size();
        if (row == n) {
            count++;
        }
        for (int j = 0; j < n; j++) {
            if (isValid(C,row,j)) {
                C[row] = j;
                DFS(C,count,row+1);
                C[row] = -1;
            }
        }
    }


    bool isValid(vector<int> C,int row,int col) {
        for (int i = 0; i < row; i++) {
            if (C[i] == col || abs(row - i) == abs(col - C[i]))
                return false;
        }
        return true;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值