backtracking 2

Same template.

Subsets

class Solution {
public:
    vector<vector<int>> res;
    
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<int> tmp;
        backtrack(nums, tmp, 0);
        return res;
    }
    
    void backtrack(vector<int>& nums, vector<int>& tmp, int start) {
        res.push_back(tmp);
        
        for (int i = start; i < nums.size(); ++i) {
            tmp.push_back(nums[i]);
            backtrack(nums, tmp, i+1);
            tmp.pop_back();
        }
    }
};

和Permutation很不同的是backtrack的条件中i的增加:而Permutation中没有增加:是因为Subsets每一个满足条件的tmp是任意子集故遍历树每一个节点都可以,而Permutation每个tmp都是包含所有元素的:所以i每次遍历都从0开始

Permutation

class Solution {
public:
    vector<vector<int>> res;
    
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> tmp;
        backtrack(nums, tmp);
        return res;
    }
    
    void backtrack(vector<int>& nums, vector<int>& tmp) {
        if (nums.size() == tmp.size()) {
            res.push_back(tmp);
            return;
        }
        for (int i = 0; i < nums.size(); ++i) {
            if (std::find(tmp.begin(), tmp.end(), nums[i]) != tmp.end()) continue; // de-dup
            tmp.push_back(nums[i]);
            backtrack(nums, tmp);
            tmp.pop_back();
        }
    }
};

Combination

  1. 和subsets类似只选部分元素, 所以istart
  2. 因为tmp最终size是给定的:所以跟permutations类似要满足terminal condition才放进res: 跟subsets不同
class Solution {
public:
    vector<vector<int>> res;
    
    vector<vector<int>> combine(int n, int k) {
        vector<int> tmp;
        backtrack(n, k, 1, tmp);
        return res;
    }
    
    void backtrack(int n, int k, int start, vector<int>& tmp) {
        if (tmp.size() == k) {
            res.push_back(tmp);
            return;
        }
        
        for (int i = start; i <= n; ++i) {
            tmp.push_back(i);
            backtrack(n, k, i+1, tmp);
            tmp.pop_back();
        }
    }
};

Additional: bit (backtracking 2.5, de facto bit manipulation)

Sum of All Subset XOR Totals

Excellent question on All binary XOR permutation subsets of integers

    1 = 001
    5 = 101
    6 = 110
1 ^ 5 = 100
1 ^ 6 = 111
5 ^ 6 = 011
1^5^6 = 010
class Solution {
    public int subsetXORSum(int[] nums) {
        int res = 0, n = nums.length;
        for (int i = 0; i < n; ++i) {
            res |= nums[i];
        }
        return res * 1 << n-1;
    }
}

Binary watch

class Solution {
    public List<String> readBinaryWatch(int num) {
        List<String> res = new ArrayList();
        for (int h = 0; h < 12; ++h) {
            for (int m = 0; m < 60; ++m) {
                if (Integer.bitCount(h * 64 + m) == num) {
                    res.add(String.format("%d:%02d", h, m));
                }
            }
        }
        return res;
    }
}

推荐阅读更多精彩内容