LeetCode Online Judge

https://github.com/zhumeng1989/MISC/blob/nightly/common/leetcode.hpp

//
// 140.Word Break II
//*http://www.cnblogs.com/superzrx/p/3354813.html
class Solution {
public:
	void DFS(string &s, int i, vector<int> &p, vector<vector<int>> &mem, vector<string> &ret) {
		for(auto&k : mem[i]) {
			p.push_back(k);
			if(k == 0) {
				string w;
				for(int k=p.size()-1; k>0; k--)
					w.append(s.substr(p[k],p[k-1]-p[k])+' ');
				w.append(s.substr(p[0]));
				ret.push_back(w);
			} else
				DFS(s, k, p, mem, ret);
			p.pop_back();
		}
	}
	vector<string> wordBreak(string s, unordered_set<string> &dict) {
		vector<string> ret;
		vector<vector<int>> mem;
		int n=s.size();
		int maxw = 0;
		for(auto&w : dict) maxw = max(maxw,int(w.size()));
		vector<bool> S(n+1,false);
		mem.resize(n+1);
		S[0] = true;
		for(int i=0; i<n; i++)
			if(S[i])
				for(int j=1; j<=min(maxw,n-i); j++)
					if(dict.find(s.substr(i,j)) != dict.end()) {
						S[i+j] = true;
						mem[i+j].push_back(i);
					}
		vector<int> path;
		DFS(s, n, path, mem, ret);
		return ret;
	}
};
//
// 139.Word Break
//*DP
// O(n^2)
class Solution {
public:
	bool wordBreak(string s, unordered_set<string> &dict) {
		int n=s.size();
		if(n==0) return true;
		vector<vector<bool>> S(n,vector<bool>(n,false));
		for(int i=0; i<n; i++)
			S[i][i] = (dict.find(s.substr(i,1))!=dict.end());
		for(int l=2; l<=n; l++) {
			for(int i=0; i+l-1<n; i++) {
				int j=i+l-1;
				if(S[i][j] = (dict.find(s.substr(i,l))!=dict.end()))
					continue;
				for(int k=i; k<j; k++)
					if(S[i][j] = (S[i][k]&&S[k+1][j]))
						break;
			}
		}
		return S[0][n-1];
	}
};
// O(n*l)
class Solution {
public:
	bool wordBreak(string s, unordered_set<string> &dict) {
		int n=s.size();
		if(n==0) return true;
		int maxw = 0;
		for(auto&w : dict) maxw = max(maxw,int(w.size()));
		vector<bool> S(n+1,false);
		S[0] = true;
		for(int i=0; i<n; i++)
			if(S[i])
				for(int j=1; j<=min(maxw,n-i); j++)
					if(dict.find(s.substr(i,j)) != dict.end())
						S[i+j] = true;
		return S[n];
	}
};
//
// 138.Copy List with Random Pointer 
/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head == NULL) return NULL;
        for(RandomListNode *h=head; h!=NULL; h=h->next->next) {
            RandomListNode *p = new RandomListNode(h->label);
            p->next = h->next;
            h->next = p;
        }
        for(RandomListNode *h=head; h!=NULL; h=h->next->next) {
            if(h->random == NULL)
                h->next->random = NULL;
            else
                h->next->random = h->random->next;
        }
        RandomListNode *copyhead = head->next;
        for(RandomListNode *h1=head, *h2=copyhead; ; h1=h1->next, h2=h2->next) {
            h1->next = h1->next->next;
            if(h1->next == NULL) break;
            h2->next = h2->next->next;
        }
        return copyhead;
    }
};
//
// 137.Single Number II
class Solution {
public:
	int singleNumber(int A[], int n) {
		vector<int> bits(32,0);
		for(int i=0; i<n; i++)
			for(int k=0; k<32; k++)
				bits[k]+=(A[i]>>k)&1;
		int ret=0;
		for(int k=0; k<32; k++)
			ret|=(bits[k]%3)<<k;
		return ret;
	}
};
//
// 136.Single Number
class Solution {
public:
	int singleNumber(int A[], int n) {
		int ret=A[0];
		for(int i=1; i<n; i++)
			ret ^= A[i];
		return ret;
	}
};
//
// 135.Candy
class Solution {
public:
	int candy(vector<int> &ratings) {
		int n=ratings.size();
		int sum=n;
		vector<int> res(n,0);
		for(int k=1,i=1; i<n; i++)
			if(ratings[i]>ratings[i-1])
				res[i]=max(k++, res[i]);
			else
				k=1;
		for(int k=1,i=n-2; i>=0; i--)
			if(ratings[i]>ratings[i+1])
				res[i]=max(k++, res[i]);
			else
				k=1;
		for(int i=0; i<n; i++)
			sum+=res[i];
		return sum;
	}
};
//
// 134.Gas Station
class Solution {
public:
	int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
		int n=gas.size();
		int sum=0;
		int total=0;
		int idx=-1;
		for(int i=0; i<n; i++) {
			total += gas[i]-cost[i];
			sum += gas[i]-cost[i];
			if(sum < 0) {
				idx = i;
				sum=0;
			}
		}
		return total<0?-1:idx+1;
	}
};
//
// 133.Clone Graph
/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if(node == NULL) return NULL;
        unordered_map<UndirectedGraphNode*,UndirectedGraphNode*> hash;
        UndirectedGraphNode *ret = new UndirectedGraphNode(node->label);
        hash[node] = ret;
        queue<UndirectedGraphNode*> Q;
        Q.push(node);
        while(!Q.empty()) {
            UndirectedGraphNode*p = Q.front();
            Q.pop();
            for(auto &v : p->neighbors) {
                if(hash.find(v) == hash.end()) {
                    hash[v] = new UndirectedGraphNode(v->label);
                    Q.push(v);
                }
                hash[p]->neighbors.push_back(hash[v]);
            }
        }
        return ret;
    }
};
//
// 132.Palindrome Partitioning II
class Solution {
public:
	int minCut(string s) {
		int n = s.length();
		if (n<2) return 0;
		vector<int> M(n,0);
		vector<vector<bool>> P(n,vector<bool>(n,false));
		for(int i=1; i<n; i++) {
			if (s[0] == s[i] && (i<3 || P[1][i-1]))
				M[i] = 0;
			else {
				M[i] = min(i, M[i-1]+1);
				for (int k=i-1; k>0; k--) {
					if (s[k] == s[i] && (i-k<3 || P[k+1][i-1])) {
						P[k][i] = true;
						M[i] = min(M[i], M[k-1]+1);
					}
				}  
			}
		}
		return M[n-1];
	}
};
//
// 131.Palindrome Partitioning
// P(i,j) = S(i)==S(j) && P(i+1,j-1)
// scan table P with i=n-1:0, j=i:n-1
class Solution {
public:
	void DFS(string&s, int i, vector<vector<bool>>&P,
		vector<vector<string>>&R, vector<string>&S){
			int n = s.size();
			if (i==n) {
				R.push_back(S);
				return;
			}
			for (int j = i; j<n; j++) {
				if(P[i][j]) {
					S.push_back(s.substr(i,j-i+1));
					DFS(s,j+1,P,R,S);
					S.pop_back();
				}
			}
	}
	vector<vector<string>> partition(string s) {
		int n = s.size();
		vector<vector<bool>> P(n,vector<bool>(n,false));
		for(int i=n-1; i>=0; i--) {
			P[i][i] = true;
			for(int j=i+1; j<n; j++) {
				if (s[i]==s[j] && (j-i<3 || P[i+1][j-1]))
					P[i][j] = true;
			}
		}
		vector<vector<string>> results;
		vector<string> ts;
		DFS(s,0, P, results, ts);
		return results;
	}
};
//
// 130.Surrounded Regions
class Solution {
public:

	void flip(vector<vector<char>> &b, int i, int j) {
		if (i<0 || i>=n || j<0 || j>=m)
			return;
		if (b[i][j] == 'O') {
			b[i][j]='A';
			flip(b, i-1, j);
			flip(b, i+1, j);
			flip(b, i, j-1);
			flip(b, i, j+1);
		}
	}

	void solve(vector<vector<char>> &board) {
		n = board.size();
		if (n==0) return;
		m = board[0].size();
		if (m==0) return;
		for(int i=0; i<n; i++) {
			flip(board, i, 0);
			flip(board, i, m-1);
		}
		for(int i=0; i<m; i++) {
			flip(board, 0, i);
			flip(board, n-1, i);
		}
		for(int i=0; i<n; i++)
			for(int j=0; j<m; j++)
				if(board[i][j] == 'O')
					board[i][j] = 'X';
		for(int i=0; i<n; i++)
			for(int j=0; j<m; j++)
				if(board[i][j] == 'A')
					board[i][j] = 'O';

	}
	int m,n;
};
//
// 129.Sum Root to Leaf Numbers
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int sumNumbers(TreeNode *root) {
        sum = 0;
        if (root == NULL) return 0;
        int X = 0;
        travel(root, X);
        return sum;
    }
    
    void travel(TreeNode* node, int X) {
        if (node == NULL) return;
        X = 10*X + node->val;
        travel(node->left, X);
        travel(node->right, X);
        if (node->left == NULL && node->right == NULL)
            sum += X;
    }
    
    int sum;
};
//
// 128.Longest Consecutive Sequence
class Solution {
public:
	int longestConsecutive(vector<int> &num) {
		unordered_map<int,int> m;
		int n = num.size();
		vector<bool> visited(n, false);
		for (int i=0; i<n; i++)
			m[num[i]] = i;
		int ml = 0;
		for (int i=0; i<n; i++) {
			if (visited[i]) continue;
			visited[i] = true;
			int j = num[i];
			int l = 1;
			for(int k=j+1; m.find(k)!=m.end() && !visited[m[k]]; k++,l++)
				visited[m[k]] = true;
			for(int k=j-1; m.find(k)!=m.end() && !visited[m[k]]; k--,l++)
				visited[m[k]] = true;
			ml = max(ml, l);
		}
		return ml;
	}
};
//
// 126.Word Ladder
class Solution {
public:
	int ladderLength(string start, string end, unordered_set<string> &dict) {
		dict.erase(start);
		dict.insert(end);
		
		queue<pair<string, int> > q;
		for (q.emplace(start, 1); !q.empty(); q.pop()) {
			string w = q.front().first;
			int l = q.front().second;
			if (w == end)
				return l;
			for (int i=0; i<w.size(); i++) {
				char tc = w[i];
				for (char c='a'; c<='z'; c++) {
					w[i] = c;
					if (dict.find(w) != dict.end()) {
						q.emplace(w, l+1);
						dict.erase(w);
					}
				}
				w[i] = tc;
			}
		}
		return 0;
	}
};
//
// 127.Word Ladder II
// http://blog.csdn.net/niaokedaoren/article/details/8884938
class Solution {
public:
	void DFS_path(unordered_map<string, vector<string> > &trs, 
		vector<string> &path, const string &w) {
			if (trs[w].size() == 0) {
				path.push_back(w);
				vector<string> curPath = path;
				reverse(curPath.begin(), curPath.end());
				pathes.push_back(curPath);
				path.pop_back();
				return;
			}

			path.push_back(w);
			for_each(trs[w].begin(), trs[w].end(), [&](const string&w){
				DFS_path(trs, path, w);
			});
			path.pop_back();
	}

	vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
		pathes.clear();
		dict.insert(start);
		dict.insert(end);
		vector<string> prev;
		unordered_map<string, vector<string> > trs;
		for_each(dict.begin(), dict.end(), [&](const string&w){
			trs[w] = vector<string>();
		});

		vector<unordered_set<string> > lay(2);
		int cur = 0;
		int pre = 1;
		lay[cur].insert(start);
		while (true) {
			cur = !cur;
			pre = !pre;
			for_each(lay[pre].begin(), lay[pre].end(), [&](const string&w){
				dict.erase(w);
			});
			lay[cur].clear();
			for_each(lay[pre].begin(), lay[pre].end(), [&](const string&w){
				for (int i=0; i<w.size(); i++) {
					string wt(w);
					for (char c='a'; c<='z'; c++) {
						wt[i] = c;
						if (dict.find(wt) != dict.end()) { 
							trs[wt].push_back(w);
							lay[cur].insert(wt);
						}
					}
				}
			});
			if (lay[cur].size() == 0)
				return pathes;
			if (lay[cur].count(end))
				break;
		}
		vector<string> path;
		DFS_path(trs, path, end);
		return pathes;
	}

	vector<vector<string> > pathes;
};
//
// 125.Valid Palindrome
class Solution {
public:
	bool isAlphanumeric(const char&c) {
		return (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9');
	}
	bool isPalindrome(string s) {
		int n = s.size();
		string st;
		st.reserve(n);
		for (int i=0; i<n; i++)
			if (isAlphanumeric(s[i]))
				st.push_back(s[i]);
		n = st.size();
		if (n == 0) return true;
		for(int i=0,j=n-1; i<j; i++,j--)
			if(tolower(st[i])!=tolower(st[j]))
				return false;
		return true;
	}
};
//
// 124.Binary Tree Maximum Path Sum
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    int travel(TreeNode *r) {
        if(r == NULL) return 0;
        int lmax = travel(r->left);
        int rmax = travel(r->right);
        maxval = max(maxval,r->val);
        maxsum = max(maxsum, lmax+rmax+r->val);
        return max(max(lmax,rmax)+r->val,0);
    }

    int maxPathSum(TreeNode *root) {
        maxval = numeric_limits<int>::min();
        maxsum = 0;
        travel(root);
        if (maxval <= 0) return maxval;
        else return maxsum;
    }
    int maxval, maxsum;
};
//
// 121.Best Time to Buy and Sell Stock
class Solution {
public:
	int maxProfit(vector<int> &prices) {
		int maxval = 0;
		int n = prices.size();
		if (n <= 1) return 0;
		int curmin = prices[0];
		for (int i=1; i<n; i++) {
			curmin = min(curmin, prices[i]);
			maxval = max(maxval, prices[i]-curmin);
		}
		return maxval;
	}
};
//
// 122.Best Time to Buy and Sell Stock II
// O(n^2), Large data timeout
class Solution {
public:
	int maxProfit(vector<int> &prices) {
		int n = prices.size();
		if (n <= 1) return 0;
		vector<int> C(n+1,0);
		for (int i=n-1; i>=0; i--) {
			int maxval = 0;
			int curmin = prices[i];
			for (int k=i+1; k<n; k++) {
				curmin = min(curmin, prices[k]);
				maxval = max(maxval, prices[k]-curmin);
				C[i] = max(maxval + C[k+1], C[i]);
			}
		}
		return C[0];
	}
};
// O(n)
class Solution {
public:
	int maxProfit(vector<int> &prices) {
		int n = prices.size();
		if (n <= 1) return 0;
		int maxval = 0;
		int curmin = prices[0];
		int curmax = prices[0];
		for (int i=1; 1; ) {
			curmin = curmax;
			for (; i<n && prices[i]<=curmin; i++)
				curmin = prices[i];
			if (i>=n) break;
			curmax = curmin;
			for (; i<n && prices[i]>=curmax; i++)
				curmax = prices[i];
			maxval += curmax-curmin;
		}
		return maxval;
	}
};
//
// 123.Best Time to Buy and Sell Stock III
class Solution {
public:
	int maxProfit(vector<int> &prices) {
		int maxval = 0;
		int n = prices.size();
		if (n <= 1) return 0;
		int curmin = prices[0];
		vector<int> l2r(n,0);
		for (int i=1; i<n; i++) {
			curmin = min(curmin, prices[i]);
			maxval = max(maxval, prices[i]-curmin);
			l2r[i] = maxval;
		}
		maxval = 0;
		int curmax = prices[n-1];
		vector<int> r2l(n,0);
		for (int i=n-2; i>=0; i--) {
			curmax = max(curmax, prices[i]);
			maxval = max(maxval, curmax-prices[i]);
			r2l[i] = maxval;
		}
		maxval = 0;
		for (int i=0; i<n; i++)
			maxval = max(maxval, l2r[i]+r2l[i]);
		return maxval;
	}
};
//
// 120.Triangle
class Solution {
public:
	int minimumTotal(vector<vector<int> > &triangle) {
		int n = triangle.size();
		if (n == 0) return 0;
		if (n == 1) return triangle[0][0];
		vector<int> e[2];
		e[0].resize(n,0);
		e[1].resize(n,0);
		e[0][0]=triangle[0][0];
		int cur = 0;
		int pre = 1;
		for (int i=1; i<n; i++) {
			cur = 1-cur;
			pre = 1-pre;
			e[cur][0] = e[pre][0]+triangle[i][0];
			for (int j=1; j<i; j++) {
				e[cur][j] = min(e[pre][j-1],e[pre][j])+triangle[i][j];
			}
			e[cur][i] = e[pre][i-1]+triangle[i][i];
		}
		int maxval = e[cur][0];
		for(int i=0; i<n; i++)
			maxval = min(maxval, e[cur][i]);
		return maxval;
	}
};
//
// 118.Pascal's Triangle
class Solution {
public:
	vector<vector<int> > generate(int numRows) {
		vector<vector<int>> ret;
		if (numRows == 0) return ret;
		vector<int> r[2];
		r[0].resize(1,1);
		r[1].resize(1,1);
		int cur = 0;
		int pre = 1;
		ret.push_back(r[cur]);
		for (int i=1; i<numRows; i++) {
			cur = 1-cur;
			pre = 1-pre;
			for (int j=1; j<i; j++)
				r[cur][j] = r[pre][j-1] + r[pre][j];
			r[cur].push_back(1);
			r[pre].push_back(1);
			ret.push_back(r[cur]);
		}
		return ret;
	}
};
//
// 119.Pascal's Triangle II
class Solution {
public:
	vector<int> getRow(int rowIndex) {
		vector<int> r[2];
		r[0].resize(1,1);
		r[1].resize(1,1);
		int cur = 0;
		int pre = 1;
		for (int i=1; i<=rowIndex; i++) {
			cur = 1-cur;
			pre = 1-pre;
			for (int j=1; j<i; j++)
				r[cur][j] = r[pre][j-1] + r[pre][j];
			r[cur].push_back(1);
			r[pre].push_back(1);
		}
		return r[cur];
	}
};
//
// 116.Populating Next Right Pointers in Each Node
/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (root == NULL) return;
        TreeLinkNode *x = root;
        while(x != NULL) {
            if (x->left != NULL)
                x->left->next = x->right;
            if (x->right != NULL) {
                x->right->next = NULL;
                if (x->next != NULL)
                    x->right->next = x->next->left;
            }
            x = x->next;
        }
        connect(root->left);
    }
};
//
// 117.Populating Next Right Pointers in Each Node II
/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (root == NULL) return;
        TreeLinkNode *x = root;
        TreeLinkNode *pre = NULL;
        TreeLinkNode *nxt = NULL;
        while(x != NULL) {
            if (pre != NULL) {
                if (x->left != NULL) {
                    pre->next = x->left;
                    pre = x->left;
                }
                if (x->right != NULL) {
                    pre->next = x->right;
                    pre = x->right;
                }
            } else {
                if (x->left != NULL) {
                    nxt = pre = x->left;
                    if (x->right != NULL) {
                        pre->next = x->right;
                        pre = x->right;
                    }
                } else {
                    if (x->right != NULL) {
                        nxt = pre = x->right;
                    }
                }
            }
            x = x->next;
        }
        connect(nxt);
    }
};
//
// 115.Distinct Subsequences
//*like LCS, DP
// C(i,j) = C(i-1,j)+C(i-1,j-1), Si==Tj
//        = C(i-1,j), Si!=Tj
// Note: 1.ns+1,nt+1, 2.C(i-1,0)=1 startup point, 3.reduce to one-dimension:
// C(j) += C(j-1), Si==Tj, reverse scan j--.
class Solution { // 80ms
public:
	int numDistinct(string S, string T) {
		int ns = S.size();
		int nt = T.size();
		if (ns<nt) return 0;
		vector<vector<int>> C(ns+1, vector<int>(nt+1,0));
		for(int i=1; i<=ns; i++) {
			C[i-1][0] = 1;
			for(int j=1; j<=nt; j++) {
				if (S[i-1] == T[j-1])
					C[i][j] = C[i-1][j] + C[i-1][j-1];
				else
					C[i][j] = C[i-1][j];
			}
		}
		return C[ns][nt];
	}
};
class Solution { // 28ms
public:
	int numDistinct(string S, string T) {
		int ns = S.size();
		int nt = T.size();
		if (ns<nt) return 0;
		vector<int> C(nt+1,0);
		C[0] = 1;
		for(int i=1; i<=ns; i++)
			for(int j=nt; j>=1; j--)
				if (S[i-1] == T[j-1])
					C[j] += C[j-1];
		return C[nt];
	}
};
//
// 114.Flatten Binary Tree to Linked List
// postorder traversal
// http://discuss.leetcode.com/questions/280/flatten-binary-tree-to-linked-list
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    void travel(TreeNode *root, TreeNode *&t) {
        if(root == NULL) return;
		// Note, right first
        travel(root->right,t);
        travel(root->left,t);
        root->right = t;
        t = root;
        root->left = NULL;
    }

    void flatten(TreeNode *root) {
        if(root == NULL) return;
        TreeNode* t = NULL;
        travel(root,t);
    }
};
//
// 113.Path Sum II
// preorder traversal, backtrack
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void travel(TreeNode *r, int s, int sum, vector<int>&path, vector<vector<int>>&ret) {
        if(r==NULL) return;
        s+=r->val;
        path.push_back(r->val);
        if(r->left == NULL && r->right == NULL && s == sum)
            ret.push_back(path);
        travel(r->left,s,sum,path,ret);
        travel(r->right,s,sum,path,ret);
        path.pop_back();
        
    }
    vector<vector<int> > pathSum(TreeNode *root, int sum) {
        vector<vector<int>> ret;
        vector<int> path;
        travel(root, 0, sum, path, ret);
        return ret;
    }
};
//
// 112.Path Sum
// preorder traversal
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool travel(TreeNode *r, int s, int sum) {
        if(r==NULL) return false;
        s+=r->val;
        if(r->left == NULL && r->right == NULL)
            if (s == sum) return true;
            else return false;
        return travel(r->left,s,sum) || travel(r->right,s,sum);
        
    }
    bool hasPathSum(TreeNode *root, int sum) {
        return travel(root, 0, sum);
    }
};
//
// 111.Minimum Depth of Binary Tree
// BFS
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int minDepth(TreeNode *root) {
        if(root==NULL) return 0;
        queue<pair<TreeNode*,int>> q;
        q.emplace(root,1);
        while(!q.empty()) {
            TreeNode* x = q.front().first;
            int depth = q.front().second;
            if(x->left == NULL && x->right == NULL)
                return depth;
            if(x->left!=NULL)
                q.emplace(x->left,depth+1);
            if(x->right!=NULL)
                q.emplace(x->right,depth+1);
            q.pop();
        }
    }
};
//
// 110.Balanced Binary Tree
// postorder traversal
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool travel(TreeNode*r, int&h) {
        if(r==NULL) {
            h=0;
            return true;
        }
        int lh, rh;
        if (!travel(r->left,lh))
            return false;
        if (!travel(r->right,rh))
            return false;
        if(abs(lh-rh) > 1)
            return false;
        else {
            h = max(lh,rh)+1;
            return true;
        }
    }
    bool isBalanced(TreeNode *root) {
        int h;
        return travel(root,h);
    }
};

//
// 109.Convert Sorted List to Binary Search Tree
//*using bottom-up approach, O(n)
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *travel(ListNode*&head,int i,int j) {
        if(i>j) return NULL;
        int m = (j+i)/2;
        TreeNode *r = new TreeNode(-1);
        r->left = travel(head,i,m-1);
        r->val = head->val;
        head = head->next;
        r->right = travel(head,m+1,j);
        return r;
    }
    TreeNode *sortedListToBST(ListNode *head) {
        int n = 0;
        ListNode*p = head;
        for(; p!=NULL; n++) p = p->next;
        return travel(head,0,n-1);
    }
};
// O(nlgn)
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *travel(ListNode *head,int n) {
        if(n<=0) return NULL;
        int m = n/2;
        ListNode*p = head;
        for(int i=0; i<m; i++) p = p->next;
        TreeNode *r = new TreeNode(p->val);
        r->left = travel(head,m);
        r->right = travel(p->next,n-m-1);
        return r;
    }
    TreeNode *sortedListToBST(ListNode *head) {
        int n = 0;
        ListNode*p = head;
        for(; p!=NULL; n++) p = p->next;
        return travel(head,n);
    }
};
//
// 108.Convert Sorted Array to Binary Search Tree
// direct index
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *travel(vector<int>&num,int i, int j) {
        if(i>j) return NULL;
        int m = (j+i)/2;
        TreeNode *r = new TreeNode(num[m]);
        r->left = travel(num,i,m-1);
        r->right = travel(num,m+1,j);
        return r;
    }
    TreeNode *sortedArrayToBST(vector<int> &num) {
        int n = num.size();
        return travel(num,0,n-1);
    }
};
//
// 107.Binary Tree Level Order Traversal II
// preorder traversal, push node to correct level vector.
// or postorder, just make sure push left before right.
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void travel(TreeNode*r, int d, vector<vector<int>>&ret) {
        if(r == NULL) return;
        if(d >= ret.size()) ret.push_back(vector<int>(1,r->val));
        else ret[d].push_back(r->val);
        travel(r->left,d+1,ret);
        travel(r->right,d+1,ret);
    }
    vector<vector<int> > levelOrderBottom(TreeNode *root) {
        vector<vector<int>> ret;
        travel(root, 0, ret);
        reverse(ret.begin(), ret.end());
        return ret;
    }
};
//
// 106.Construct Binary Tree from Inorder and Postorder Traversal
//*find the root, then recursively build the tree
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *travel(vector<int> &inorder, int i, int j, vector<int> &postorder) {
        if(i>j) return NULL;
        TreeNode *r = new TreeNode(postorder.back());
        postorder.pop_back();
        int m = i;
        for(int k=i; k<=j; k++)
            if(inorder[k] == r->val)
            { m = k; break; }
        r->right = travel(inorder, m+1, j, postorder);
        r->left = travel(inorder, i, m-1, postorder);
        return r;
    }
    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
        return travel(inorder, 0, inorder.size()-1, postorder);
    }
};
//
// 105.Construct Binary Tree from Preorder and Inorder Traversal
//*find the root, then recursively build the tree
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *travel(vector<int> &inorder, int i, int j, vector<int> &preorder, int&ii) {
        if(i>j) return NULL;
        TreeNode *r = new TreeNode(preorder[ii]);
        ii++;
        int m = i;
        for(int k=i; k<=j; k++)
            if(inorder[k] == r->val)
            { m = k; break; }
        r->left = travel(inorder, i, m-1, preorder, ii);
        r->right = travel(inorder, m+1, j, preorder, ii);
        return r;
    }
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        int k=0;
        return travel(inorder, 0, inorder.size()-1, preorder, k);
    }
};
//
// 104.Maximum Depth of Binary Tree
// DFS, preorder traversal
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void travel(TreeNode *r, int d) {
        if(r==NULL) return;
        if(r->left == NULL && r->right == NULL)
            maximum = max(maximum, d+1);
        travel(r->left, d+1);
        travel(r->right, d+1);
    }
    int maxDepth(TreeNode *root) {
        maximum = 0;
        travel(root, 0);
        return maximum;
    }
    int maximum;
};
// iteratively
class Solution {
public:
	int maxDepth(TreeNode *root) {
		int maximum = 0;
		stack<TreeNode*> s;
		TreeNode* r = root;
		int d = 0;
		while(true) {
			if (r != NULL) {
				s.push(r);
				if(r->left == NULL && r->right == NULL)
					maximum = max(maximum, int(s.size()));
				r = r->left;
			} else {
				while(!s.empty() && s.top()==NULL) s.pop();
				if(s.empty()) break;
				r = s.top();
				r = r->right;
				s.pop();
				s.push(NULL); // push dummy
			}
		}
		return maximum;
	}
};
//
// 103.Binary Tree Zigzag Level Order Traversal
// Like 107. Could use Stack.
/**
 * 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<vector<int> > zigzagLevelOrder(TreeNode *root) {
        vector<vector<int>> ret;
        stack<TreeNode*> q[2];
        int cur = 0;
        int pre = 1;
        q[cur].push(root);
        while(!q[cur].empty()) {
            cur = 1-cur;
            pre = 1-pre;
            vector<int> v;
            while(!q[pre].empty()) {
                TreeNode* x = q[pre].top();
                q[pre].pop();
                if (x==NULL) continue;
                v.push_back(x->val);
                if(cur==1) {
                    q[cur].push(x->left);
                    q[cur].push(x->right);
                }else{
                    q[cur].push(x->right);
                    q[cur].push(x->left);
                }
            }
            if (!v.empty())
                ret.push_back(v);
        }
        return ret;
    }
};
//
// 102.Binary Tree Level Order Traversal
// Like 107.
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void travel(TreeNode*r, int d, vector<vector<int>>&ret) {
        if(r == NULL) return;
        if(d >= ret.size()) ret.push_back(vector<int>(1,r->val));
        else ret[d].push_back(r->val);
        travel(r->left,d+1,ret);
        travel(r->right,d+1,ret);
    }
    vector<vector<int> > levelOrder(TreeNode *root) {
        vector<vector<int>> ret;
        travel(root, 0, ret);
        return ret;
    }
};
//
// 101.Symmetric Tree
// order and rorder traversal
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void preorderTravel(TreeNode*r, vector<int>&v) {
        if(r==NULL) return;
        v.push_back(r->val);
        preorderTravel(r->left, v);
        preorderTravel(r->right, v);
    }
    void rpreorderTravel(TreeNode*r, vector<int>&v) {
        if(r==NULL) return;
        v.push_back(r->val);
        rpreorderTravel(r->right, v);
        rpreorderTravel(r->left, v);
    }
    void inorderTravel(TreeNode*r, vector<int>&v) {
        if(r==NULL) return;
        inorderTravel(r->left, v);
        v.push_back(r->val);
        inorderTravel(r->right, v);
    }
    void rinorderTravel(TreeNode*r, vector<int>&v) {
        if(r==NULL) return;
        rinorderTravel(r->right, v);
        v.push_back(r->val);
        rinorderTravel(r->left, v);
    }
    bool isSymmetric(TreeNode *root) {
        vector<int> order;
        vector<int> rorder;
        preorderTravel(root,order);
        rpreorderTravel(root,rorder);
        if (order != rorder)
            return false;
        else {
            order.clear();
            rorder.clear();
            inorderTravel(root,order);
            rinorderTravel(root,rorder);
            return order == rorder;
        }
    }
};
//
// 100.Same Tree
// preorder same and postorder same? no!!!, since there are same value
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool travel2(TreeNode *p, TreeNode *q) {
        if(p==NULL && q==NULL) return true;
        if(p==NULL && q!=NULL) return false;
        if(p!=NULL && q==NULL) return false;
        if(p->val != q->val) return false;
        return travel2(p->left, q->left) && travel2(p->right, q->right);
    }
    bool isSameTree(TreeNode *p, TreeNode *q) {
        return travel2(p, q);
    }
};
//
// 99.Recover Binary Search Tree
//*http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.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:
    void travel(TreeNode*r) {
        if(r==NULL) return;
        travel(r->left);
        if(mistake[cur]!=NULL && mistake[cur]->val > r->val) {
            if(cur==0) cur++;
            mistake[2] = r;
        }
        mistake[cur] = r;
        travel(r->right);
    }
    void recoverTree(TreeNode *root) {
        cur = 0;
        mistake.clear();
        mistake.push_back(NULL);
        mistake.push_back(NULL);
        mistake.push_back(NULL);
        travel(root);
        swap(mistake[0]->val, mistake[2]->val);
    }
    vector<TreeNode*> mistake;
    int cur;
};
//
// 98.Validate Binary Search Tree
// inorder traversal
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool travel(TreeNode*r) {
        if(r==NULL) return true;
        if (!travel(r->left)) return false;
        if(pre!=NULL && pre->val >= r->val) return false; // Equal???
        pre = r;
        if(!travel(r->right)) return false;
        return true;
    }
    bool isValidBST(TreeNode *root) {
        pre = NULL;
        return travel(root);
    }
    TreeNode*pre;
};
//
// 97.Interleaving String
//*DP. B(i,j) = S1(i)==S3(i+j+1) && B(i-1,j) || S2(j)==S3(i+j+1) && B(i,j-1)
// Note: i,j start from 0
// http://fisherlei.blogspot.com/2012/12/leetcode-interleaving-string.html
class Solution {
public:
	bool isInterleave(string s1, string s2, string s3) {
		int n1 = s1.size();
		int n2 = s2.size();
		int n3 = s3.size();
		if(n1+n2 != n3) return false;
		vector<bool> B[2];
		int cur = 0;
		int pre = 1;
		B[cur].resize(n2+1, false);
		B[pre].resize(n2+1, false);
		B[pre][0] = true;
		for(int j=1; j<=n2; j++)
			B[pre][j] = B[pre][j-1] && s2[j-1]==s3[j-1];
		for(int i=1; i<=n1; i++) {
			B[cur][0] = B[pre][0] && s1[i-1]==s3[i-1];
			for(int j=1; j<=n2; j++)
				B[cur][j] = (s1[i-1]==s3[i+j-1] && B[pre][j]) || (s2[j-1]==s3[i+j-1] && B[cur][j-1]);
			cur = 1-cur;
			pre = 1-pre;
		}
		return B[pre][n2];
	}
};
//
// 96.Unique Binary Search Trees
class Solution {
public:
	int numTrees(int n) {
		if (n<=0) return 0;
		vector<int> N(n+1, 0);
		N[0]=1;
		for (int i=1; i<=n; i++)
			for (int j=1; j<=i; j++)
				N[i] += N[j-1]*N[i-j];
		return N[n];
	}
};
//
// 95.Unique Binary Search Trees II
//*recursively build left and right tree
// http://fisherlei.blogspot.com/2013/03/leetcode-unique-binary-search-trees-ii.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<TreeNode*> generate(int l, int r) {
		vector<TreeNode*> subTree;
		if(l>r) {
			subTree.push_back(NULL);
			return subTree;
		}
		for(int i=l; i<=r; i++) {
			vector<TreeNode*> left = generate(l, i-1);
			vector<TreeNode*> right = generate(i+1, r);
			for(int j=0; j<left.size(); j++)
			{
				for(int k=0; k<right.size(); k++)
				{
					TreeNode*node = new TreeNode(i);
					node->left = left[j];
					node->right = right[k];
					subTree.push_back(node);
				}
			}
		}
		return subTree;
	}
	vector<TreeNode *> generateTrees(int n) {
		if(n==0) return generate(1,0);
		return generate(1, n);
	}
};
//
// 94.Binary Tree Inorder Traversal
//*iteratively
/**
 * 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<TreeNode*> s;
        TreeNode* r = root;
        while(true) {
            if (r != NULL) {
                s.push(r);
                r = r->left;
            } else {
                if(s.empty()) break;
                r = s.top();
                s.pop();
                ret.push_back(r->val);
                r = r->right;
            }
        }
        return ret;
    }
};

//
// 93.Restore IP Addresses
// DFS
class Solution {
public:
	void DFS(string&s, int k, string path, vector<string>&ret, int d) {
		if (s.size()-k > (4-d)*3) return;
		if (s.size()-k < (4-d)) return;
		if (k==s.size() && d==4) {
			path.pop_back();
			ret.push_back(path);
			return;
		}
		int ch = 0;
		for(int i=k; i<k+3; i++) {
			ch = ch*10 + s[i] - '0';
			if (ch<=255) {
				path.push_back(s[i]);
				DFS(s, i+1, path+'.', ret, d+1);
			}
			if (ch == 0) break;
		}
	}
	vector<string> restoreIpAddresses(string s) {
		vector<string> ret;
		string path;
		DFS(s, 0, path, ret, 0);
		return ret;
	}
};
//
// 92.Reverse Linked List II
// how to be bug free only once?
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        ListNode h(0);
        h.next = head;
        ListNode* p1 = &h;
        ListNode* p2 = head;
        for(int i=0; i<m-1; i++)
            p1 = p1->next;
        for(int i=0; i<n; i++)
            p2 = p2->next;
        ListNode* tp = p1;
        p1 = p1->next;
        for(int i=0; i<=n-m; i++) {
            ListNode* t = p1->next;
            p1->next = p2;
            p2 = p1;
            p1 = t;
        }
        tp->next = p2;
        return h.next;
    }
};
//
// 90.Subsets II
//*DFS
class Solution {
public:
	void DFS(vector<int> &S, int k) {
		if(k==n) {
			ret.push_back(subset);
			return;
		}
		int m=1;
		for(; k+m<n && S[k]==S[k+m]; m++);
		for(int i=0; i<=m; i++) {
			DFS(S,k+m);
			subset.push_back(S[k]);
		}
		for(int i=0; i<=m; i++)
			subset.pop_back();
	}
	vector<vector<int> > subsetsWithDup(vector<int> &S) {
		n = S.size();
		ret.clear();
		subset.clear();
		sort(S.begin(), S.end());
		DFS(S, 0);
		return ret;
	}
	int n;
	vector<vector<int> > ret;
	vector<int> subset;
};
//
// 91.Decode Ways
// DP, a lot of cases
class Solution {
public:
	int numDecodings(string s) {
		int n = s.size();
		if (n==0 || s[0]=='0') return 0;
		vector<int> D(n+1,0);
		D[0] = D[1] = 1;
		for(int i=1; i<n; i++) {
			if (s[i]!='0')
				D[i+1] = D[i];
			else if(s[i-1] > '2' || s[i-1] < '1')
				return 0;
			int ch = (s[i-1]-'0')*10+s[i]-'0';
			if (ch <= 26 && ch >= 10)
				D[i+1] += D[i-1];

		}
		return D[n];
	}
};
//
// 89.Gray Code
// 

//
// 88.Merge Sorted Array
// Trivial merge, in-place
class Solution {
public:
	void merge(int A[], int m, int B[], int n) {
		int k = m+n-1;
		m--; n--;
		while(k>=0 && m>=0 && n>=0) {
			if(A[m] > B[n])
				A[k--] = A[m--];
			else
				A[k--] = B[n--];
		}
		while(k>=0 && m>=0)
			A[k--] = A[m--];
		while(k>=0 && n>=0)
			A[k--] = B[n--];
	}
};
//
// 87.Scramble String
// 

//
// 86.Partition List
// Straight forward
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *partition(ListNode *head, int x) {
        ListNode h(0);
        h.next = head;
        ListNode*lp = &h;
        ListNode*pp = &h;
        for(ListNode*p = head; p!=NULL; p=p->next) {
            if(p->val < x) {
                pp->next = p->next;
                p->next = lp->next;
                lp->next = p;
				lp = p;
            }
            pp = p;
        }
        return h.next;
    }
};
//
// 85.Maximal Rectangle
// DP, Like 4.4 in dynamic_programming? No! here is Rectangle, not square

//
// 84.Largest Rectangle in Histogram
// http://www.geeksforgeeks.org/largest-rectangle-under-histogram/
// O(n)
class Solution {
public:
	int largestRectangleArea(vector<int> &h) {
		stack<int> p;
		int i = 0, m = 0;
		h.push_back(0);
		while(i < h.size()) {
			if(p.empty() || h[p.top()] <= h[i])
				p.push(i++);
			else {
				int t = p.top();
				p.pop();
				m = max(m, h[t] * (p.empty() ? i : i - p.top() - 1 ));
			}
		}
		return m;
	}
};
//
// 83.Remove Duplicates from Sorted List
// Sorted List is trival
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        if(head==NULL) return head;
        ListNode* cur = head->next;
        ListNode* pre = head;
        while(cur!=NULL) {
            if(pre->val == cur->val) {
                pre->next = cur->next;
                delete cur;
            } else 
                pre = cur;
            cur = pre->next;
        }
        return head;
    }
};
//
// 82.Remove Duplicates from Sorted List II
// Sorted List is trival
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        ListNode h(0);
        h.next = head;
        ListNode* cur = head;
        ListNode* pre = &h;
        while(cur!=NULL && cur->next!=NULL) {
            if(cur->val == cur->next->val) {
                int val = cur->val;
                while(cur!=NULL && cur->val == val) {
                    pre->next = cur->next;
                    delete cur;
                    cur = pre->next;
                }
            } else {
                pre = cur;
                cur = pre->next;
            }
        }
        return h.next;
    }
};
//
// 81.Search in Rotated Sorted Array II
// refer to 33.

//
// 80.Remove Duplicates from Sorted Array II
// refer to 26.

//
// 79.Word Search
// DFS
class Solution {
public:
	bool DFS(vector<vector<char> > &board, int i, int j, string word, int k) {
		if(board[i][j]!=word[k]) return false;
		if(k==l-1) return true;
		char tmp = board[i][j];
		board[i][j] = '$';
		if(i-1>=0 && DFS(board,i-1,j,word,k+1)) return true;
		if(j-1>=0 && DFS(board,i,j-1,word,k+1)) return true;
		if(i+1< m && DFS(board,i+1,j,word,k+1)) return true;
		if(j+1< n && DFS(board,i,j+1,word,k+1)) return true;
		board[i][j] = tmp;
		return false;
	}
	bool exist(vector<vector<char> > &board, string word) {
		l=word.size();
		if(l==0) return true;
		m=board.size();
		if(m==0) return false;
		n=board[0].size();
		if(n==0) return false;
		for(int i=0; i<m; i++)
			for(int j=0; j<n; j++)
				if(DFS(board,i,j,word,0))
					return true;
		return false;
	}
	int m,n,l;
};
//
// 78.Subsets
// DFS
class Solution {
public:
	void DFS(vector<int> &S, int k) {
		if(k==n) {
			ret.push_back(subset);
			return;
		}
		DFS(S,k+1);
		subset.push_back(S[k]);
		DFS(S,k+1);
		subset.pop_back();
	}
	vector<vector<int> > subsets(vector<int> &S) {
		n = S.size();
		ret.clear();
		subset.clear();
		sort(S.begin(), S.end());
		DFS(S, 0);
		return ret;
	}
	int n;
	vector<vector<int> > ret;
	vector<int> subset;
};
//
// 77.Combinations
//*
class Solution {
public:
	void combine(int i, int n, int k, vector<int>&p) {
		for(; i<=n; i++) {
			p.push_back(i);
			if(k==1) {
				ret.push_back(p);
			} else {
				combine(i+1, n, k-1, p);
			}
			p.pop_back();
		}
	}
	vector<vector<int> > combine(int n, int k) {
		ret.clear();
		vector<int> path;
		combine(1, n, k, path);
		return ret;
	}
	vector<vector<int>> ret;
};
//
// 76.Minimum Window Substring
//*
class Solution {
public:
	string minWindow(string S, string T) {
		vector<int> cn(256,0);
		for(auto &c : T) cn[c]++;
		int n=S.size();
		int m=T.size();
		int count=0;
		int minimum=n;
		int begin=0;
		vector<int> wcn(256,0);
		for(int i=0,k=0; k<n; k++) {
			if(cn[S[k]] == 0) continue;
			if(wcn[S[k]] < cn[S[k]]) count++;
			wcn[S[k]]++;
			if (count == m) {
				for(; cn[S[i]]==0 || wcn[S[i]] > cn[S[i]]; i++)
					if(wcn[S[i]] > cn[S[i]])
						wcn[S[i]]--;
				if(minimum > k-i+1) {
					minimum = k-i+1;
					begin = i;
				}
			}
		}
		return count<m? "" : S.substr(begin, minimum);
	}
};
//
// 75.Sort Colors
class Solution {
public:
	void sortColors(int A[], int n) {
		int pl=0, pr=n-1;
		for(int i=0; i<=pr; ) {
			if(A[i]==0)
				swap(A[i++],A[pl++]);
			else if(A[i]==2)
				swap(A[i],A[pr--]);
			else
				i++;
		}
	}
};
//
// 74.Search a 2D Matrix 
class Solution {
public:
	bool bsearch(vector<vector<int> > &matrix, int l, int r, int t) {
		if(l>r) return false;
		int mid=(r+l)/2;
		int i = mid/n;
		int j = mid%n;
		if(matrix[i][j]==t) return true;
		else if(matrix[i][j] > t)
			return bsearch(matrix,l,mid-1,t);
		else
			return bsearch(matrix,mid+1,r,t);
	}
	bool searchMatrix(vector<vector<int> > &matrix, int target) {
		m=matrix.size();
		if(m==0) return false;
		n=matrix[0].size();
		if(n==0) return false;
		int k=m*n;
		return bsearch(matrix,0,k-1,target);
	}
	int m,n;
};
//
// 73.Set Matrix Zeroes 
class Solution {
public:
	void setZeroes(vector<vector<int> > &matrix) {
		int m=matrix.size();
		if(m==0) return;
		int n=matrix[0].size();
		if(n==0) return;
		bool m0=false, n0=false;
		for(int i=0; i<m; i++) if(matrix[i][0]==0) m0=true;
		for(int j=0; j<n; j++) if(matrix[0][j]==0) n0=true;
		for(int i=1; i<m; i++)
			for(int j=1; j<n; j++)
				if(matrix[i][j]==0)
					matrix[i][0]=matrix[0][j]=0;
		for(int i=1; i<m; i++)
			for(int j=1; j<n; j++)
				if(matrix[i][0]==0 || matrix[0][j]==0)
					matrix[i][j]=0;
		if(m0) for(int i=0; i<m; i++) matrix[i][0]=0;
		if(n0) for(int j=0; j<n; j++) matrix[0][j]=0;
	}
};
//
// 72.Edit Distance
// O(m*n) space
class Solution {
public:
	int minDistance(string word1, string word2) {
		int m=word1.size();
		int n=word2.size();
		vector<vector<int> > E(m+1,vector<int>(n+1,0));
		for(int i=0; i<=m; i++) E[i][0]=i;
		for(int j=0; j<=n; j++) E[0][j]=j;
		for(int i=1; i<=m; i++)
			for(int j=1; j<=n; j++)
				E[i][j] = min(min(E[i][j-1],E[i-1][j])+1,E[i-1][j-1]+(word1[i-1]==word2[j-1]?0:1));
		return E[m][n];
	}
};
// O(min(m,n)) space
class Solution {
public:
	int minDistance(string word1, string word2) {
		int m=word1.size();
		int n=word2.size();
		if(n>m) {
			swap(m,n); swap(word1,word2);
		}
		vector<int> E(n+1,0);
		for(int j=0; j<=n; j++) E[j]=j;
		for(int i=1; i<=m; i++) {
			int lt=i-1; E[0]=i;
			for(int j=1; j<=n; j++) {
				int tmp = min(min(E[j],E[j-1])+1,lt+(word1[i-1]==word2[j-1]?0:1));
				lt=E[j]; E[j]=tmp;
			}
		}
		return E[n];
	}
};
//
// 71.Simplify Path
//*
class Solution {
public:
	string simplifyPath(string path) {
		int n=path.size();
		vector<string> S;
		string name;
		for(int i=0; i<n; ) {
			int m=0;
			for(; i<n; i++) {
				if(path[i]=='.')
					m++;
				else if(path[i]=='/') {
					if(m>=2 && !S.empty()) S.pop_back();
					m=0;
				} else
					break;
			}
			if(i==n) {
				if(m>=2 && !S.empty()) S.pop_back();
				break;
			}
			while(m--) name.push_back('.');
			for(; i<n && path[i]!='.' && path[i]!='/'; i++) name.push_back(path[i]);
			S.push_back(name);
			name.clear();
		}
		for(auto &s:S)
			name.append('/'+s);
		return S.empty()? "/":name;
	}
};
//
// 70.Climbing Stairs 
class Solution {
public:
	int climbStairs(int n) {
		if(n<=2) return n;
		int w_1 = 2;
		int w_2 = 1;
		int ret = 0;
		for(int i=3; i<=n; i++) {
			ret = w_1+w_2;
			w_2 = w_1;
			w_1 = ret;
		}
		return ret;
	}
};
//
// 69.Sqrt(x)
class Solution {
public:
	int sqrt(int x) {
		if(x<2) return x;
		long long l=0;
		long long r=x;
		while(l<=r) {
			long long m = (l+r)/2;
			if(m*m>x)
				r=m-1;
			else if(m*m<x)
				l=m+1;
			else
				return m;
		}
		return r;
	}
};
//
// 68.Text Justification 
class Solution {
public:
	vector<string> fullJustify(vector<string> &words, int L) {
		int n = words.size();
		vector<string> ret;
		if(n==0) return ret;
		vector<string> S;
		string line;
		int k=0;
		while(1) {
			int count = words[k].size();
			S.push_back(words[k]);
			for(k++; k<n && count+1+words[k].size()<=L; k++) {
				S.push_back(words[k]);
				count+=(1+words[k].size());
			}
			if(k==n) { // last line
				for(auto &s:S) line.append(s+' ');
				line.resize(L,' ');
				ret.push_back(line);
				break;
			}
			int nitv = S.size()-1;
			int nspace = L-count+nitv;
			int u,v;
			if(nitv == 0) {
				u = 0; v = 0;
			} else {
				u = nspace/nitv; v = nspace%nitv;
			}
			int i=0;
			for(; i<v; i++) line.append(S[i]).append(u+1,' ');
			for(; i<nitv; i++) line.append(S[i]).append(u,' ');
			line.append(S[i]);
			if(nitv == 0) line.resize(L,' ');
			ret.push_back(line);
			S.clear();
			line.clear();
		}
		return ret;
	}
};
//
// 67.Plus One
class Solution {
public:
	vector<int> plusOne(vector<int> &digits) {
		// Note: The Solution object is instantiated only once and is reused by each test case.
		int n=digits.size();
		for(int i=n-1; i>=0; i--) {
			digits[i]++;
			if(digits[i]<10) return digits;
			else digits[i]=0;
		}
		digits.insert(digits.begin(),1);
		return digits;
	}
};
//
// 66.

//
// Permutations 
//*
class Solution {
public:
	void permute(int k,vector<int> &num) {
		if (k<num.size()) {
			for(int i=k; i<num.size(); i++) {
				swap(num[i], num[k]);
				permute(k+1, num);
				swap(num[i], num[k]);
			}
		} else {
			ret.push_back(num);
		}
	}
	vector<vector<int> > permute(vector<int> &num) {
		ret.clear();
		permute(0, num);
		return ret;
	}
	vector<vector<int> > ret;
};


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值