Showing posts with label combination. Show all posts
Showing posts with label combination. Show all posts

Thursday, June 18, 2015

Day 109, 215, ##, Kth Largest Element in an Array, Combination Sum III, Contains Duplicate

Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
Note: 
You may assume k is always valid, 1 ≤ k ≤ array's length.
----------------------------------------------
quick-select。因为是in-place,注意storedIndex的初始值为left
class Solution {
public:
    void swap(vector<int> &nums,int index_1, int index_2) {
        int temp = nums[index_1];
        nums[index_1] = nums[index_2];
        nums[index_2] = temp;
    }

    int partition(vector<int> &nums,int left, int right) {
        int mid = left + (right - left) / 2;
        swap(nums,mid,right);
        
        int storedIndex = left;
        for (int i = left; i < right; i++) {
            if (nums[i] <= nums[right]) {
                swap(nums,i,storedIndex);
                storedIndex++;
            }    
        }
        swap(nums,storedIndex,right);
        
        return storedIndex;
    }

    int findKthLargest(vector<int>& nums, int k) {
        int left = 0, right = nums.size() - 1;
        
        while (left <= right) {
            int pivot = partition(nums,left,right);
            if (pivot == nums.size() - k) {
                return nums[pivot];
            }
            if (pivot < nums.size() - k) {
                left = pivot + 1;
            }else {
                right = pivot - 1;
            }
        }
        
        return -1;
    }
};

Combination Sum III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Ensure that numbers within the set are sorted in ascending order.

Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]

Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]]
-------------------------------------------------
class Solution {
public:
    void dfs(vector<vector<int>> &rt, vector<int> cur, int startNum, int k, int sum) {
        if (k == 0 && sum == 0) {
            rt.push_back(cur);
            return;
        }
        
        if (k < 0 || sum < 0) return;
        
        for (int i = startNum; i < 10; i++) {
            vector<int> temp = cur;
            temp.push_back(i);
            dfs(rt,temp,i + 1,k - 1,sum - i);
        }
        
    }

    vector<vector<int>> combinationSum3(int k, int n) {
        vector<vector<int>> rt;
        vector<int> cur;
        dfs(rt,cur,1,k,n);
        
        return rt;
    }
};
类似
class Solution {
public:
    void helper(vector<vector<int> > &rt, vector<int> cur, int target,int k, int index) {
        if (k == 0 && target == 0) {
            rt.push_back(cur);
            return;
        }
        if (k < 0 || target < 0 || index > 9) return;
        
        helper(rt,cur,target,k,index + 1);
        cur.push_back(index);
        helper(rt,cur,target - index,k - 1, index + 1);
    }

    vector<vector<int>> combinationSum3(int k, int n) {
        vector<vector<int>> rt;
        vector<int> cur;
        helper(rt,cur,n,k,1);
        
        return rt;
    }
};
Contains Duplicate
Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. ------------------------------------------------
hash set
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int> st;
        for (int i = 0; i < nums.size(); i++) {
            if (st.find(nums[i]) != st.end()) {
                return true;
            }
            st.insert(nums[i]);
        }
        
        return false;
    }
};
sort
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i - 1] == nums[i]) {
                return true;
            }
        }
        
        return false;
    }
};

Wednesday, December 25, 2013

Day 65 - 1, #89, #90, #94, Gray Code, Subsets II, Binary Tree Inorder Traversal

Gray Code
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00 - 0
01 - 1
11 - 3
10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
---------------------------------------------------------------------------------
Solution#1, see patterns below

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> ret;
        ret.push_back(0);
        for (int i = 0; i < n; i++) {
            int size = ret.size();
            int bit = 1 << i;
            for (int j = size - 1; j >= 0; j--) {
                ret.push_back(ret[j] + bit);
            }
        }
        return ret;
    }
};
Solution#2, from internet
class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> ret;
        int count = 0x01 << n;
        for(int i = 0 ; i < count; ++i) {
            ret.push_back(i ^ (i>>1));
        }
        return ret;
    }
};
Subsets II
Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:

  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.
For example,
If S = [1,2,2], a solution is:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
----------------------------------------------------------
Solution #1. Similar to #78 Subsets
Add a hashset to skip duplicates
class Solution {
public:
    void subsets(vector<int> S, vector<vector<int> > &ret, vector<int> cur) {
        int length = S.size();
        unordered_set<int> mapping;
        for (int i = 0; i < length; i++) {
            vector<int> temp = cur;
            int head = S[0];
            S.erase(S.begin());
            if (mapping.find(head) == mapping.end()) {
                mapping.insert(head);
                temp.push_back(head);
                ret.push_back(temp);
                subsets(S,ret,temp);
            }
        }
    }

    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        sort(S.begin(),S.end());
        vector<vector<int> > ret;
        vector<int> cur;
        ret.push_back(cur);
        subsets(S,ret,cur);
        return ret;
    }
};
Update Nov-19-2014
Solution#2 iterative
如果 不重复,从头插。
如果是重复数字,只需插入到前一次所插入的数列中

class Solution {
public:
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        vector<int> empty;
        vector<vector<int> > rt;
        rt.push_back(empty);
        sort(S.begin(),S.end());
        
        int size = 0;
        for (int i = 0; i < S.size(); i++) {
            int start = 0;
            if (i > 0 && S[i] == S[i - 1]) {
                start = size;
            }
            
            size = rt.size();
            for (; start < size; start++) {
                vector<int> temp = rt[start];
                temp.push_back(S[i]);
                rt.push_back(temp);
            }
        }
         
        return rt;
    }
};
Java, 递归,去重
class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> rt = new ArrayList<>();
        dfs(rt, nums, 0, new ArrayList<>());
        
        return rt;
    }
    
    private void dfs(List<List<Integer>> rt, int[] nums, int index, List<Integer> sofar) {
        rt.add(sofar);
        
        for (int i = index; i < nums.length; i++) {
            if (i > index && nums[i] == nums[i - 1]) continue;
            List<Integer> tmp = new ArrayList<>(sofar);
            tmp.add(nums[i]);
            dfs(rt, nums, i + 1, tmp);
        }
    }
}
迭代
class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> rt = new ArrayList<>();
        rt.add(new ArrayList<Integer>());
        Arrays.sort(nums);
        
        int lastSize = 0;
        for (int i = 0; i < nums.length; i++) {
            List<List<Integer>> rt_tmp = new ArrayList<>();
            
            int size = rt.size();
            if (i > 0 && nums[i] == nums[i - 1]) {
                size = lastSize;
            }
                
            for (int j = size; j > 0; j--) {
                int index = rt.size() - j;
                List<Integer> inner = new ArrayList<>(rt.get(index));
                inner.add(nums[i]);
                rt_tmp.add(inner);
            }
            lastSize = rt_tmp.size();
            rt.addAll(rt_tmp);
        }
        
        return rt;
    }
}

Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3
return [1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
-----------------------------------------------
Iterative approach
Solution #1, add a boolean value to indicate visited status
Other solutions:   

http://leetcode.com/2010/04/binary-search-tree-in-order-traversal.html
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
        vector<int> ret;
        stack<pair<TreeNode*,bool> > s;
        s.push(make_pair(root,false));
        
        while (!s.empty()) {
            pair<TreeNode*,bool> p = s.top();
            if (p.first != NULL) {
                if (p.second == false) {
                    s.top().second = true;
                    s.push(make_pair(p.first->left,false));
                }else {
                    ret.push_back(p.first->val);
                    s.pop();
                    s.push(make_pair(p.first->right,false));
                }
            }else {
                s.pop();
            }
        }
        return ret;
    }
};
Update Nov-19-2014
basic idea: when a node is traversed for the second time, its value will be printed
当每一个node的左节点为NULL时,则需要打印这个node
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
        stack<TreeNode *> st;
        vector<int> rt;
        
        while (!st.empty() || root != NULL) {
            if (root) {
                st.push(root);
                root = root->left;
            }else {
                rt.push_back(st.top()->val);
                root = st.top()->right;
                st.pop();
            }
        }
        return rt;
    }
};
*表示怀疑*方法三,用2个stack,一个用来存第一次visit的node,一个是第二次visit的node

方法四,Threaded binary tree. O(n) time, O(1) space 每往左走一个node,把之前node贴在它左子树的最右下角, 这是根据inorder traversal的特性决定的。算法见leetcode
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List inorderTraversal(TreeNode root) {
        List rt = new ArrayList<>();
        TreeNode cur = root;
        
        while (cur != null) {
            if (cur.left != null) {
                root = cur;
                cur = cur.left;
                TreeNode rightMost = cur;
                
                while (rightMost.right != null) {
                    rightMost = rightMost.right;
                }
                
                rightMost.right = root;
                root.left = null;
                
            }else {
                rt.add(cur.val);
                cur = cur.right;
            }
        }
        
        return rt;
    }
}

Wednesday, December 18, 2013

Day 57 #37, #40, Sudoku Solver, Combination Sum II

Search in Rotated Sorted Array
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'.
You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.
------------------------------------------
set up three 2D arrays as caches to store used numbers in each row, column and sub-block

class Solution {
public:
    bool sudoku (vector<vector<char> > &board, vector<vector<bool> > &rows, 
            vector<vector<bool> > &cols, vector<vector<bool> > &subs, int index) {
        if (index == 81) {
            return true;
        }
        int rowIndex = index / 9;
        int colIndex = index % 9;
        
        if (board[rowIndex][colIndex] == '.') {
            for (int i = 0; i < 9; i++) {
                if (!(rows[rowIndex][i] || cols[colIndex][i] || subs[(rowIndex / 3) * 3 + colIndex / 3][i])) {
                    board[rowIndex][colIndex] = '1' + i;
                    rows[rowIndex][i] = true;
                    cols[colIndex][i] = true;
                    subs[rowIndex / 3 * 3 + colIndex / 3][i] = true;
                    
                    // if conditions is false, backtrack
                    if (!sudoku(board, rows, cols, subs,index + 1)) {
                        board[rowIndex][colIndex] = '.';
                        rows[rowIndex][i] = false;
                        cols[colIndex][i] = false;
                        subs[rowIndex / 3 * 3 + colIndex / 3][i] = false;
                    }else {
                        return true;
                    }
                }
            }
            return false;
        }else {
            // if slot is filled already
            return sudoku(board, rows, cols, subs,index + 1);
        }
    }

    void solveSudoku(vector<vector<char> > &board) {
        // declare and populate caches
        vector<vector<bool> > rows(9,vector<bool>(9,false));
        vector<vector<bool> > cols(9,vector<bool>(9,false));
        vector<vector<bool> > subs(9,vector<bool>(9,false));
        for (int rowIndex = 0; rowIndex < 9; rowIndex++) {
            for (int colIndex = 0; colIndex < 9; colIndex++) {
                if (board[rowIndex][colIndex] != '.') {
                    int val = board[rowIndex][colIndex] - '1';
                    rows[rowIndex][val] = true;
                    cols[colIndex][val] = true;
                    subs[(rowIndex / 3) * 3 + colIndex / 3][val] = true;
                }
            }
        }
        
        // recursive call starts here
        sudoku(board,rows,cols,subs,0);
    }
};
Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
------------------------------------------------------------
Similar to #39 Combination Sum

class Solution {
public:
    void comb (vector<int>& candidates, int target, vector<vector<int> > &ret, vector<int> cur,int start) {
        if (target == 0) {
            ret.push_back(cur);
        }else {
            for (int i = start; i < candidates.size(); i++) {
                if (target - candidates[i] >= 0) {
                    vector<int> v= cur;
                    v.push_back(candidates[i]);
                    comb(candidates,target-candidates[i],ret,v,i+1); // no element can be re-used, so i + 1
                }
                
                // skip duplicates 
                while (candidates.size() - 1 > i && candidates[i] == candidates[i + 1]) {
                    i++;
                }
            }
        }
    }

    vector<vector<int> > combinationSum2(vector<int> &num, int target) {
        sort(num.begin(),num.end());
        vector<vector<int> > ret;
        vector<int> cur;
        comb(num,target,ret,cur,0);
        return ret;
    }
};
类似
class Solution {
public:
    void helper(vector<vector<int>> &rt,vector<int>& candidates, vector<int> cur,int target,int index) {
        if (target == 0) {
            rt.push_back(cur);
            return;
        }
        
         if (target < 0 || index >= candidates.size()) return;
        
        vector<int> temp = cur;
        temp.push_back(candidates[index]);
        helper(rt,candidates,temp,target - candidates[index],index + 1);

        while (index + 1 < candidates.size() && candidates[index] == candidates[index + 1]) {
            index++;
        }
        helper(rt,candidates,cur,target,index + 1);
        
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> rt;
        vector<int> cur;
        helper(rt,candidates,cur,target,0);
        
        return rt;
    }
};

Tuesday, June 18, 2013

Day 38, 77, 78 Combinations, Subsets

Combinations
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
--------------------------------------------------------
combination, note that in this case, [1,2] and [2,1] are considered the same
we can use a stack instead of vector for vector<int> num
class Solution {
public:
    void comb (vector<vector<int> >&ret, vector<int> num, vector<int> cur, int k) {
        if (k == 0) {
            ret.push_back(cur);
        }else {
            int size = num.size(); 
            for (int i=0;i<size;i++) {
                vector<int> temp = cur;
                temp.push_back(num[0]);
                num.erase(num.begin());
                comb(ret,num,temp,k-1);
            }
        }
    }

    vector<vector<int> > combine(int n, int k) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<int> num(n);
        for (int i=0;i<n;i++) {
            num[i] = 1+i;
        }
        vector<int> cur;
        vector<vector<int> > ret;
        comb(ret,num,cur,k);
        return ret;
    }
};
Update on Sep-16-2014
class Solution {
public:
    void comb (vector<vector<int> > &rt, vector<int> cur, int n, int k, int index) {
        if (k == 0) {
            rt.push_back(cur);
            return;
        }
        
        for (int i = index; i <= n + 1 - k; i++) {
            vector<int> temp = cur;
            temp.push_back(i);
            comb(rt,temp,n,k - 1,i + 1);
        }
    }

    vector<vector<int> > combine(int n, int k) {
        vector<vector<int> > rt;
        vector<int> v;
        comb(rt,v,n,k,1);
        return rt;
    }
};

同subsets的bit operation的方法
class Solution {
public:
    void helper(vector<vector<int>> &rt,vector<int> cur, int n, int k, int index) {
        if (k == 0) {
            rt.push_back(cur);
            return;
        }
        if (k < 0 || index > n) return;
        
        helper(rt,cur,n,k,index + 1);
        cur.push_back(index);
        helper(rt,cur,n,k - 1,index + 1);
    }

    vector<vector<int>> combine(int n, int k) {
        vector<vector<int> > rt;
        vector<int> cur;
        helper(rt,cur,n,k,1);
        
        return rt;
    }
};


Subsets
Given a set of distinct integers, S, return all possible subsets.
Note:
  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.
For example,
If S = [1,2,3], a solution is:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
--------------------------------------------------
Solution #1 recursive, Combination
class Solution {
public:
    void sub (vector<vector<int> > &ret, vector<int> S, vector<int> cur) {
        if (S.size() != 0) {
            int size = S.size();
            for (int i=0;i<size;i++) {
                vector<int> temp = cur;
                temp.push_back(S[0]);
                S.erase(S.begin());
                ret.push_back(temp);
                sub(ret,S,temp);
            }
        }
    }

    vector<vector<int> > subsets(vector<int> &S) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        sort(S.begin(),S.end());
        vector<vector<int> > ret;
        vector<int> cur;
        ret.push_back(cur);
        sub(ret,S,cur);
        return ret;
    }
};
Update on Sep-17-2014
class Solution {
public:
    void sub(vector<vector<int> > &rt, vector<int> cur, vector<int> S, int index) {
        rt.push_back(cur);
        
        for (int i = index; i < S.size(); i++) {
            vector<int> temp = cur;
            temp.push_back(S[i]);
            sub(rt,temp,S,i + 1);
        }
    }

    vector<vector<int> > subsets(vector<int> &S) {
        sort(S.begin(),S.end());
        vector<vector<int> > rt;
        vector<int> v;
        sub(rt,v,S,0);
        
        return rt;
    }
};
Update on Nov-01-2014
Solution #2, Bitmap
For each S it has 2^S.size() subsets and each for loop iteration generates one subset
1 2 3
------
0 0 0
0 0 1
0 1 0
0 1 1
...
class Solution {
public:
    vector<vector<int> > subsets(vector<int> &S) {
        int numOfSubsets = 1 << S.size();
        sort(S.begin(),S.end());
        vector<vector<int> > rt;
        
        for (int i = 0; i < numOfSubsets; i++) {
            int pos = 0;
            int bitMask = i;
            vector<int> sub;
            
            while (bitMask > 0) {
                if ((bitMask & 1) == 1) {
                    sub.push_back(S[pos]);
                }
                bitMask >>= 1;
                pos++;
            }
            rt.push_back(sub);
        }
        
        return rt;
    }
};

Update on Nov-18-2014
Solution #3 iterative
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int> > rt;
        vector<int> cur;
        rt.push_back(cur);
        sort(nums.begin(),nums.end());
        
        for (int i = 0; i < nums.size(); i++) {
            vector<vector<int> > temp = rt;
            for (int j = 0; j < temp.size(); j++) {
                temp[j].push_back(nums[i]);
                rt.push_back(temp[j]);
            }
        }
        
        return rt;
    }
};




Update on July-5th-2015
每个数字都可以为 “有” 或 “无”
class Solution {
public:
    void helper(vector<vector<int> > &rt, vector<int> nums, vector<int> cur,int index) {
        if (index == nums.size()) {
            rt.push_back(cur);
            return;
        }
        
        helper(rt,nums,cur,index + 1);
        cur.push_back(nums[index]);
        helper(rt,nums,cur,index + 1);
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int> > rt;
        vector<int> cur;
        helper(rt,nums,cur,0);
        
        return rt;
    }
};

ToDo, 以上所有解法要再看一次

Saturday, June 1, 2013

Day 32, 30,39,46, Substring with Concatenation of All Words, Combination Sum,Permutations

Substring with Concatenation of All Words
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]
You should return the indices: [0,9].
(order does not matter).
------------------------------------------------------------------------
use two maps to count occurrences of all patterns, iterate through S to check if each word in L exactly occurs once in current part of S
solution is from internet
this is a boring and tasteless question
time and space complexity?
notice the conversion (int)S.size() in for loop
class Solution {  
public:  
    vector<int> findSubstring(string S, vector<string> &L) {  
        map<string, int> words;  
        map<string, int> curStr;  
        for(int i = 0; i < L.size(); ++i)  
            ++words[L.at(i)];  
        int N = L.size();  
        vector<int> ret;  
        if(N <= 0)   return ret;  
        int M = L.at(0).size();  
        for(int i = 0; i <= (int)S.size()-N*M; ++i)  
        {  
            curStr.clear();  
            int j = 0;  
            for(j = 0; j < N; ++j)  
            {  
                string w = S.substr(i+j*M, M);  
                if(words.find(w) == words.end())  
                    break;  
                ++curStr[w];  
                if(curStr[w] > words[w])  
                    break;  
            }  
            if(j == N)  ret.push_back(i);  
        }  
        return ret;  
    }  
};
Update on Sep-11-2014
The idea is similar to Longest Substring Without Repeating Characters. Each word has the same length and can be seen as a unique(or not) character.
A slightly different implementation is it can re-assign a new map at the beginning of outer loop.
Update on Feb-17-2015
COME_BACK
inner loop里的算法
#1 如果找不到当前word,重新设置map和start,重新开始
#2 如果找到且数量 > 0
#3 如果找到且数量 == 0: 从start开始pop旧的word,直到找到当前的为止

因为所有词为无序,不用保证维护当前的数组, 如
1 - 2 -..........3 - 2 - 1, 假设扫到3时已经找到所有的词
class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        unordered_map<string,int> dic;
        for (int i = 0; i < words.size(); i++) {
            if (dic.find(words[i]) == dic.end()) {
                dic[words[i]] = 1;
            }else {
                dic[words[i]]++;
            }
        }
        
        vector<int> rt;
        int wordLen = words[0].length();

        for (int i = 0; i < wordLen; i++) {
            int start = i,count = 0;
            unordered_map<string,int> temp = dic;
            for (int j = i; j < s.length(); j += wordLen) {
                string word = s.substr(j,wordLen);
                if (temp.find(word) == temp.end()) {
                    count = 0;
                    temp = dic;
                    start = j + wordLen;
                    continue;
                }else if (temp[word] > 0) {
                    temp[word]--;
                    count++;
                    if (count == words.size()) rt.push_back(start);
                }else if (temp[word] == 0) {
                    while (true) {
                        string begin = s.substr(start,wordLen);
                        if (begin == word) {
                            start += wordLen;
                            if (count == words.size()) rt.push_back(start);
                            break;
                        }
                        temp[begin]++;
                        count--;
                        start += wordLen;
                    }
                }
            }    
        }
        
        return rt;
    }
};

Java, updated on Sep-25th-2018
3种情况:
1. map有单词且次数大于0
2. map有单词但次数等于0
3. map不包含单词
2和3可以揉成一个branch

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        
        Map<String, Integer> map = getMap(words);
        List<Integer> rt = new ArrayList<>();
        if (s.length() == 0 || words.length == 0) return rt;
        
        for (int i = 0; i < words[0].length(); i++) {
            rt.addAll(findSub(s, i, map, words[0].length(), words.length));    
        }
        
        return rt;
    }
    
    private List<Integer> findSub(String s, int i, Map<String, Integer> map, int len, int count) {
        List<Integer> rt = new ArrayList<>();
        Map<String, Integer> local = new HashMap<>(map);
        int start = i;
        int tempCount = count;
        
        while (i < s.length() - len + 1) {
            String word = s.substring(i, i + len);
            if (local.containsKey(word) && local.get(word) > 0) {
                local.put(word, local.get(word) - 1);
                i += len;
                tempCount--;
                
                if (tempCount == 0) {
                    rt.add(start);
                    String old = s.substring(start, start + len);
                    local.put(old, local.get(old) + 1);
                    start += len;
                    tempCount++;
                }
            }else {
                while (true) {
                    String old = s.substring(start, start + len);
                    if (old.equals(word)) {
                        start += len;
                        break;
                    }
                    local.put(old, local.get(old) + 1);
                    start += len;
                    tempCount++;
                }   
                i += len;
            }
        }
        
        return rt;
    }
    
    private Map<String, Integer> getMap(String[] words) {
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        
        return map;
    }
}
}
Combination Sum
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, � , ak) must be in non-descending order. (ie, a1 ? a2 ? � ? ak).
  • The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]
-------------------------------------------------------------
combination

class Solution {
public:
    void comb (vector<int> &candidates, int target,vector<vector<int> > &ret,vector<int> cur,int start) {
        if (target == 0) {
            ret.push_back(cur);
        }else {
            for (int i=start;i<candidates.size();i++) {
                if (target - candidates[i] >= 0) {
                    vector<int> v = cur;  // Attention here!!!
                    v.push_back(candidates[i]);
                    comb(candidates,target-candidates[i],ret,v,i);
                }
            }
        }
    }

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        sort(candidates.begin(),candidates.end());
        vector<vector<int> > ret;
        vector<int> cur;
        comb(candidates,target,ret,cur,0);
        return ret;
    }
};
class Solution {
public:
    void comb(vector<vector<int> > &rt, vector<int> &candidates, vector<int> cur, int target, int index) {
        if (target == 0) {
            rt.push_back(cur);
            return;
        } 
        if (index >= candidates.size() || target < 0) return;
        
        comb(rt,candidates,cur,target,index + 1);
        cur.push_back(candidates[index]);
        comb(rt,candidates,cur,target - candidates[index],index);
    } 

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int> > rt;
        vector<int> cur;
        comb(rt,candidates,cur,target,0);
        
        return rt;
    }
};
Permutations
Given a collection of numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
--------------------------------------------------------------------
class Solution {
public:
    void per (vector<int> num,vector<int> cur,vector<vector<int> > &ret) {
        if (num.size() == 0) {
            ret.push_back(cur);
        }
        for (int i=0;i<num.size();i++) {
            vector<int> v = cur;
            vector<int> w = num;
            v.push_back(w[i]);
            w.erase(w.begin()+i);
            per(w,v,ret);
        }
    }

    vector<vector<int> > permute(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<int> > ret;
        vector<int> cur;
        per(num,cur,ret);
        return ret;
    }
};

#1 以index为分界线,来区分已经使用和未使用的集合(此条不一定为正确,需看代码)
#2 换句话说,每一个recursive call,都遍历所有未使用的数字确定在index(n次)
index = 0: 123, 213, 321
index = 1: 132, 231, 312
index = 2: 插入
class Solution {
public:
    void swap(vector<int> &nums,int i,int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    void per(vector<vector<int> > &rt, vector<int> &nums, int index) {
        if (nums.size() == index) {
            rt.push_back(nums);
            return;
        }
        
        for (int i = index; i < nums.size(); i++) {
            swap(nums,i,index);
            per(rt,nums,index + 1);
            swap(nums,i,index); // 此行可以不加,结果同样正确,因为每一次都会确定一个数
        }
    }

    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int> > rt;
        per(rt,nums,0);
        
        return rt;
    }
};