Showing posts with label Recursion. Show all posts
Showing posts with label Recursion. Show all posts

Saturday, May 23, 2015

Regular Expression Matching

来源:Leetcode

原帖:http://oj.leetcode.com/problems/regular-expression-matching/

题目:
Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") ? false
isMatch("aa","aa") ? true
isMatch("aaa","aa") ? false
isMatch("aa", "a*") ? true
isMatch("aa", ".*") ? true
isMatch("ab", ".*") ? true
isMatch("aab", "c*a*b") ? true  zero or more

思路:
http://www.cnblogs.com/zuoyuan/p/3781773.html
解题思路:正则表达式匹配的判断。网上很多的解法是用递归做的,用java和c++都可以过,但同样用python就TLE,说明这道题其实考察的不是递归。而是动态规划,使用动态规划就可以AC了。这里的'*'号表示重复前面的字符,注意是可以重复0次的。
先来看递归的解法:
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。

代码:
 class Solution {  
 public:  
   bool isMatch(const char *s, const char *p) {  
     if (*p == '\0') return *s == '\0';  
     if (*(p+1) == '*') {  
       if (isMatch(s, p+2)) return true; // match 0  
       while (*s && (*s == *p || *p == '.')) { // match 1,2,...  
         if (isMatch(s+1, p+2)) return true;  
         s++;  
       }  
     } else if (*s && (*p == *s || *p == '.') && isMatch(s+1, p+1)) // always check *s  
         return true;  
     return false;  
   }  
 };  
   
 // dp solution  
 class Solution {  
 public:  
   bool isMatch(const char* s, const char* p) {  
     if (*p == '\0') return *s == '\0';  
     int M = strlen(s), N = strlen(p);  
     vector<vector<bool> > dp(M+1, vector<bool>(N+1, false)); // 前i个字符in s和前j个字符in p的匹配  
     dp[0][0] = true;  
     for (int j = 0; j < N; ++j)  
       dp[0][j+1] = p[j] == '*' ? (j >= 1 && dp[0][j-1]) : false;   
     for (int i = 0; i < M; ++i) {  
       for (int j = 0; j < N; ++j) {  
         if (s[i] == p[j] || p[j] == '.') {  
           dp[i+1][j+1] = dp[i][j];  
         } else if (p[j] == '*') {  
           dp[i+1][j+1] = dp[i+1][j-1] || ((s[i] == p[j-1] || p[j-1] == '.') && dp[i][j+1]);  
         }  
       }  
     }  
     return dp[M][N];  
   }  
 };  

Monday, May 18, 2015

Combinations

来源:Leetcode

原帖:http://oj.leetcode.com/problems/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],
 ]

代码:
 class Solution {  
 public:  
   vector<vector<int> > combine(int n, int k) {  
     vector<vector<int> > res;  
     vector<int> onecom;  
     combineHelper(n, k, 1, onecom, res);  
     return res;  
   }  
     
   void combineHelper(int n, int k, int start, vector<int> &onecom, vector<vector<int> > &res) {  
     int m = onecom.size();  
     if (m == k) {  
       res.push_back(onecom);  
       return;  
     }  
     for (int i = start; i <= n - (k - m) + 1; ++i) { // index = n-(k-m);  
       onecom.push_back(i);  
       combineHelper(n, k, i + 1, onecom, res);  
       onecom.pop_back();  
     }  
   }  
 };  

Combination Sum II

来源:Leetcode

原帖:http://oj.leetcode.com/problems/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, a1 <= a2 <= ... <= 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]

代码:
 class Solution {  
 public:  
   vector<vector<int>> combinationSum2(vector<int> &num, int target) {  
     vector<vector<int> > res;  
     sort(num.begin(), num.end());  
     vector<int> com;  
     combinationSum2Helper(num, target, 0, com, res);  
     return res;  
   }  
   
   void combinationSum2Helper(const vector<int> &num, int target, int start, vector<int> &com, vector<vector<int>> &res) {  
     if (target == 0) {  
       res.push_back(com);  
       return;  
     }  
     for (int i = start; i < num.size() && num[i] <= target; ++i) {  
       if (i > start && num[i] == num[i - 1]) {  
         continue; // avoid duplicates  
       }  
       com.push_back(num[i]);  
       combinationSum2Helper(num, target - num[i], i + 1, com, res);  
       com.pop_back();  
     }  
   }  
 };  


Combination Sum I

来源:Leetcode

原帖:http://oj.leetcode.com/problems/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]
Solution: Sort & Recursion.

代码:
 class Solution {  
 public:  
   vector<vector<int>> combinationSum(vector<int> &candidates, int target) {  
     vector<vector<int> > res;  
     sort(candidates.begin(), candidates.end()); // 如果没有要求结果是非下降序列,则sort是非必要的  
     vector<int> com;  
     combinationSumHelper(candidates, target, 0, com, res);  
     return res;  
   }  
   
   void combinationSumHelper(const vector<int> &num, int target, int start, vector<int> &com, vector<vector<int>> &res) {  
     if (target == 0) {  
       res.push_back(com);  
       return;  
     }  
     for (int i = start; i < num.size() && target >= num[i]; ++i) {  
       com.push_back(num[i]);  
       combinationSumHelper(num, target - num[i], i, com, res);  
       com.pop_back();  
     }  
   }  
 };  

Coin Change

来源:g4g, Facebook Onsite

原帖:http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/

题目:
Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter. For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.

代码:
 #include <iostream>  
 #include <string>  
 #include <vector>  
 using namespace std;  
   
 int changeCoins(int m, vector<int>& amount, int idx) {  
   if (idx == 0) return m % amount[idx] == 0 ? 1 : 0;  
   int count = 0;  
   for (int i = 0; i * amount[idx] <= m; ++i) {  
     count += changeCoins(m - i * amount[idx], amount, idx - 1);  
   }  
   return count;  
 }  
   
 vector<int> amount = {2, 3, 5};  
 int main() {  
   int m = 7;  
   int idx = amount.size();  
   cout << changeCoins(m, amount, idx-1);  
   return 0;  
 }  

二维dp
 int count( int S[], int m, int n )  
 {  
   int i, j, x, y;  
    
   // We need n+1 rows as the table is consturcted in bottom up manner using   
   // the base case 0 value case (n = 0)  
   int table[n+1][m];  
     
   // Fill the enteries for 0 value case (n = 0)  
   for (i=0; i<m; i++)  
     table[0][i] = 1;  
    
   // Fill rest of the table enteries in bottom up manner   
   for (i = 1; i < n+1; i++)  
   {  
     for (j = 0; j < m; j++)  
     {  
       // Count of solutions including S[j]  
       x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;  
    
       // Count of solutions excluding S[j]  
       y = (j >= 1)? table[i][j-1]: 0;  
    
       // total count  
       table[i][j] = x + y;  
     }  
   }  
   return table[n][m-1];  
 }  
    

Friday, May 15, 2015

199 Binary Tree Right Side View

来源:Leetcode

原帖:https://leetcode.com/problems/binary-tree-right-side-view/

题目:
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
For example:
Given the following binary tree,
       1            <---
     /   \
    2     3         <---
     \     \
      5     4       <---
You should return [1, 3, 4].

代码:
 /**  
  * Definition for a binary tree node.  
  * struct TreeNode {  
  *   int val;  
  *   TreeNode *left;  
  *   TreeNode *right;  
  *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
  * };  
  */  
 class Solution {  
 public:  
   void dfs(TreeNode* root, int level, vector<int>& res) {  
     if (!root) return;  
     if (res.size() == level) {  
       res.push_back(root->val);  
     } else {  
       res[level] = root->val;  
     }  
     dfs(root->left, level+1, res);  
     dfs(root->right, level+1, res);  
   }  
     
   vector<int> rightSideView(TreeNode* root) {  
     if (!root) return {};  
     vector<int> res;  
     dfs(root, 0, res);  
     return res;  
   }  
 };  

Find K Largest Elements in BST

来源:EPI

原帖:EPI 11.11. pg. 312.

题目:
Given the root of a BST and an integer k, design a function that finds the k largest elements in this BST. For example, if the input to your function is the BST in Figure 11.1 on Page 87 and k = 3, your function should return <53, 47, 43>.

代码:
 struct TreeNode {  
   int val;  
   TreeNode* left;  
   TreeNode* right;  
   TreeNode(int v) : val(v), left(NULL), right(NULL) {}  
 };  
   
   
 void find_k_largest_in_BST_helper(TreeNode* root, int k, vector<int> &k_elements) {  
   if (!root || k_element.size() == k) {  
     return;  
   }  
   // Perform reverse inorder traversal  
   if (root && k_elements.size() < k) {  
     find_k_largest_in_BST_helper(root->right, k, k_elements);  
     if (k_elements.size() < k) {  
       k_elements.push_back(root->val);  
       find_k_largest_in_BST_helper(root->left, k, k_elements);  
     }  
   }  
 }  
   
 vector<int> find_k_largest_in_BST(TreeNode* root, int k) {  
   vector<int> k_elements;  
   find_k_largest_in_BST_helper(root, k , k_elements);  
   return k_elements;  
 }  

Serialize & Deserialize A Tree

来源:EPI, Facebook Interview

原帖:http://fisherlei.blogspot.com/2013/03/interview-serialize-and-de-serialize.html

题目:
A very frequent interview question. Suppose you have a tree, how could you serialize it to file and revert it back? For example,
         1
      /    \
     2      3
      \     /  
       4   5  
      /  \
     6    7

[Thoughts]
一个比较简单直接的做法是,通过前序遍历来做,把所有空节点当做“#”来标示。那么这棵树可以表示为
             1
          /     \
         2        3
       /   \     /   \
     #      4    5     #
          /   \
         6     7
        /  \  /  \
       #   # #    #
那么前序遍历的结果就是: {'1','2','#','4','6','#','#','7','#','#','3','5','#','#','#'}; 代码如下:
参考 http://fisherlei.blogspot.com/2013/03/interview-serialize-and-de-serialize.html

代码:
 // Tree serialize   
 struct TreeNode {  
   int val;  
   TreeNode* left;  
   TreeNode* right;  
   TreeNode(int v) : val(v), left(NULL), right(NULL) {}  
 };  
   
 void serialize(TreeNode* root, vector<char> &result) {  
   if (root == NULL) {  
     result.push_back('#'); // 表示终结结点  
     return;  
   }  
   result.push_back(root->val + '0');  
   serialize(root->left, result);  
   serialize(root->right, result);  
 }  
   
 // de-serialize  
 TreeNode* deserialize(const vector<char> &num, int &index) {  
   if (index >= num.size()) {  
    return NULL;  
   }   
   if (num[index] == '#') {  
     index++;  
     return NULL;  
   }  
   TreeNode *root = new TreeNode(num[index] -'0');  
   index++;  
   root->left = Deserialize(num, index);  
   root->right = Deserialize(num, index);  
   return root;  
 }  
   
 int main() {  
   vector<char> numbers = {'1','2','#','4','6','#','#','7','#','#','3','5','#','#','#'};  
   int index = 0;  
   TreeNode* root = deserialize(number, index);  
   vector<char> res;  
   serialize(root, res);  
   return 0;  
 }  

Deserialize Tree的stack解法
EPI 6.8. pg. 236.
Reconstructing A Binary Tree From A Preorder Traversal With Marker. Design an O(n) time algorithm for reconstructing a binary tree from a preorder visit sequence that uses null to mark empty children. How would you modify your reconstruction algorithm if the sequence corresponded to a postorder or inorder walk.

代码:
 #define null 0;  
 TreeNode* reconstruct_preorder(const vector<int>& preorder) {  
   stack<TreeNode*> s;  
   // traversal back to forth  
   for (auto it = preorder.crbegin(); it != preorder.crend(); ++it) {  
     if (!(*it)) {  
       s.push(NULL);  
     } else {  
       TreeNode* l = s.top(); s.pop();  
       TreeNode* r = s.top(); s.pop();  
       TreeNode* root = new TreeNode(*it);  
       root->left = l;  
       root->right = r;  
       s.push(root);  
     }  
   }   
   return s.top();  
 }  



Min-BST

来源:EPI

原帖:EPI 11.6 pg. 307

题目:
A min-first BST is one in which the minimum key is stored at the root; each key in the left subtree is less than every key in the right subtree. The subtress themselves are min-first BSTs. Write a function that takes a min-first BST T and a key k, and returns true iff T contains k.

代码:
 class TreeNode {  
 public:  
   int data;  
   TreeNode* left;  
   TreeNode* right;  
   TreeNode(int d) : data(d), left(NULL), right(NULL) {}  
 };  
   
   
 bool search_min_first_BST(TreeNode* r, int k) {  
   if (!r || r->data > k) {  
     return false;  
   } else if (r->data == k) {  
     return true;  
   } else if (search_min_first_BST(r->left, k)) {  
     return true;  
   }  
   return (!r->left || r->left->data < k) && search_min_first_BST(r->right, k);  
 }  

K Balanced Tree

来源:EPI

原帖:EPI 6.2. pg. 230

题目:
Define a node in a binary tree to be k-balanced if the difference in the number of nodes in its left and right subtrees is no more than k. Design an algorithm that takes as input a binary tree and positive
integer k, and returns a node u in the binary tree such that u is not k-balanced, but all of u's descendants are k-balanced. If no such node exists, return null. For example, when applied to the binary tree in Figure 6.1 on Page 55, your algorithm should return Node J if k = 3.

代码:
 struct TreeNode {  
   int val;  
   TreeNode* left;  
   TreeNode* right;  
   TreeNode(int v) : val(v), left(NULL), right(NULL) {}  
 };  
   
 pair<TreeNode*, int> find_non_k_balanced_node_helper(TreeNode* root, int k) {  
   // Empty tree  
   if (!root) {   
     return {NULL, 0};  
   }  
   // Early return if left subtree is not k-balanced  
   auto L = find_non_k_balanced_node_helper(root->left, k);  
   if (L.first) {  
     return L;  
   }  
   // Early return if right subtree is not k-balanced  
   auto R = find_non_k_balanced_node_helper(root->right, k);  
   if (R.first) {  
     return R;  
   }  
   int node_num = L.second + R.second + 1; // #nodes in n  
   if (abs(L.second - R .second) > k) {  
     return {root, node_num};  
   }  
   return {NULL, node_num};  
 }  
   
 TreeNode* find_non_k_balanced_node(TreeNode* root, int k) {  
   return find_non_k_balanced_node_helper(root, k).first;  
 }  
   

Thursday, May 14, 2015

Convert BST To Double Linked List

来源:EPI

原帖:EPI 11.9; EPI 6.9;

题目:
Design an algorith that takes as input a BST B and returns a sorted doubly linked list on the same elements. Your algorithm should not allocate any new nodes. The original BST does not have to be preserved; use its nodes as the nodes of the resulting list, as shown in Figure 11.4 on the previous page.

代码:
 // convert binary search tree to double linked list  
 struct TreeNode {  
   int val;  
   TreeNode* left;   
   TreeNode* right;  
   TreeNode(int v) : val(v), left(NULL), right(NULL) {}  
 };  
   
 void bst2dll(TreeNode* root, TreeNode* &head, TreeNode* &tail) {  
   if (!root) return;  
   bst2dll(root->left, head, tail);  
   if (!head) {  
     head = tail = root;  
   } else {  
     tail->right = root;  
     root->left = tail;  
     tail = root;  
   }  
   TreeNode* right = root->right;  
   root->right = NULL;  
   bst2dll(right, head, tail);  
 }  
   
 TreeNode* bst2dll(TreeNode* root) {  
   TreeNode *head = NULL, *tail = NULL;  
   bst2dll(root, head, tail);  
   return head;  
 }  

Construct Binary Tree from Inorder and Postorder Traversal

来源:

原帖:https://oj.leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

题目:
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

代码:
 /**  
  * Definition for binary tree  
  * struct TreeNode {  
  *   int val;  
  *   TreeNode *left;  
  *   TreeNode *right;  
  *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
  * };  
  */  
   
 // 69ms  
 class Solution {  
 public:  
   TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {  
     return buildTreeHelper(inorder.begin(), postorder.begin(), inorder.size());  
   }  
   
   TreeNode *buildTreeHelper(vector<int>::iterator inorder, vector<int>::iterator postorder, int length) {  
     if (length <= 0) return NULL;  
     auto it = find(inorder, inorder + length, *(postorder + length - 1));  
     int left_len = it - inorder;  
     TreeNode *root = new TreeNode(*(postorder + length - 1));  
     root->left = buildTreeHelper(inorder, postorder, left_len);  
     root->right = buildTreeHelper(inorder + left_len + 1, postorder + left_len, length - left_len - 1);  
     return root;  
   }  
 };  
   
 // 25 ms using hashmap  
 class Solution {  
 public:  
   TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {  
     if(inorder.size() != postorder.size()) return NULL;  
     unordered_map<int, int> idx;  
     for(int i=0; i<inorder.size(); i++){  
       idx[inorder[i]] = i;  
     }  
     return build(inorder, postorder, 0, 0, inorder.size(), idx);  
   }  
     
   TreeNode *build(vector<int> &inorder, vector<int> &postorder, int ii, int pi, int N, unordered_map<int, int> &idx){  
     if(N == 0) return NULL;  
     int r = postorder[pi+N-1], lN = idx[r] - ii, rN = N-lN-1;  
     TreeNode *root = new TreeNode(r);  
     root->left = build(inorder, postorder, ii, pi, lN, idx);  
     root->right = build(inorder, postorder, ii+lN+1, pi+lN, rN, idx);  
     return root;  
   }  
 };  
   

Construct Binary Tree from Preorder and Inorder Traversal

来源:Leetcode

原帖:https://oj.leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

题目:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in 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 *buildTree(vector<int> &preorder, vector<int> &inorder) {  
     if (preorder.size() != inorder.size()) return NULL;  
     return buildTreeHelper(preorder.begin(), inorder.begin(), preorder.size());  
   }  
   
   TreeNode *buildTreeHelper(vector<int>::iterator preorder, vector<int>::iterator inorder, int length) {  
     if (length <= 0) return NULL;  
     auto it = find(inorder, inorder + length, *preorder);  
     int ll = it - inorder, rl = length - ll - 1;  
     TreeNode *root = new TreeNode(*preorder);  
     root->left = buildTreeHelper(preorder + 1, inorder, ll);  
     root->right = buildTreeHelper(preorder + 1 + ll, inorder + ll + 1, rl);  
     return root;  
   }  
 };  
     
 class Solution {  
 public:  
   typedef vector<int>::iterator ITERATOR;  
   TreeNode* buildTreeHelper(ITERATOR preorder, ITERATOR inorder, int length, unordered_map<int, ITERATOR>& map) {  
     if (length <= 0) return NULL;  
     auto it = map[*preorder];  
     int ll = it - inorder, rl = length - ll - 1;  
     TreeNode* root = new TreeNode(*preorder);  
     root->left = buildTreeHelper(preorder+1, inorder, ll, map);  
     root->right = buildTreeHelper(preorder+1+ll, inorder+ll+1, rl, map);  
     return root;  
   }  
   
   TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {  
     if (preorder.size() != inorder.size()) return NULL;  
     unordered_map<int, ITERATOR> map;  
     for (auto it = inorder.begin(); it != inorder.end(); ++it) {  
       map[*it] = it;  
     }  
     return buildTreeHelper(preorder.begin(), inorder.begin(), preorder.size(), map);  
   }  
 };  
   


Form A Linked List From the Leaves Of A Binary Tree

来源:EPI

原帖:EPI 6.10 pg. 237.

题目:
Given a binary tree, write a function which forms a linked list from the leaves of the binary tree. The leaves should appear in left-to-right order. For example, when applied to the binary tree in Figure 6.1 on Page 55, your function should return <D, E, H, M, N, P>.

代码:
 struct BinaryTree {  
   int data;  
   BinaryTree* left;  
   BinaryTree* right;  
   BinaryTree(int d) : data(d), left(NULL), right(NULL) {}  
 };  
   
 void connect_leaves_helper(BinaryTree* root, list<BinaryTree*>& l) {  
   if (root) {  
     if (!root->left && !root->right) {  
       l.push_back(root);  
       return;  
     } else {  
       connect_leaves_helper(root->left, l);  
       connect_leaves_helper(root->right, l);  
     }  
   }  
 }  
   
 vector<BinaryTree*> connect_leaves(BinaryTree* root) {  
   vector<BinaryTree*> L;  
   connect_leaves_helper(root, L);  
   return L;  
 }  

Recover Binary Search Tree

来源:Leetcode

原帖:http://oj.leetcode.com/problems/recover-binary-search-tree/

题目:
Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure.

代码:
 struct TreeNode {  
   int val;  
   TreeNode *left;  
   TreeNode *right;  
   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
 };  
   
 class Solution {  
 public:  
   //inorder traversal, space O(n)  
   void inorderTraversal(TreeNode *root, vector<TreeNode*> &inorder) {  
     if (!root) return;  
     inorderTraversal(root->left, inorder);  
     inorder.push_back(root);  
     inorderTraversal(root->right, inorder);  
   }  
   
   // 1, 2, 3, 4, 5 -> 1, 3, 2, 4, 5  
   // 1, 2, 3, 4, 5 -> 1, 4, 3, 2, 5  
   void recoverTree(TreeNode *root) {  
     vector<TreeNode *> inorder;  
     inorderTraversal(root, inorder);  
     TreeNode *first = NULL, *second = NULL;  
     for (int i = 1; i < inorder.size(); ++i) {  
       if (inorder[i - 1]->val < inorder[i]->val) {  
         continue;          
       }  
       if (!first) first = inorder[i - 1];  
       second = inorder[i]; // seceond must be fixed when first = NULL  
     }  
     swap(first->val, second->val); // swap values  
   }  
 };  
   
 class Solution {  
 public:  
   //Inorder traversal with 2 pointers  
   void recoverTree(TreeNode *root) {  
     TreeNode* prev = NULL, *first = NULL, *second = NULL;  
     recoverTreeHelper(root, prev, first, second);  
     swap(first->val, second->val);  
   }  
   
   void recoverTreeHelper(TreeNode* root, TreeNode* &prev, TreeNode* &first, TreeNode* &second) {  
     if (root == NULL) return;  
     //if (first && second) return; // BUG! find 2 pointers.  
     recoverTreeHelper(root->left, prev, first, second);  
     if (prev && prev->val > root->val) {  
       if (first == NULL) first = prev;          
       second = root; //两种情况, 相邻或者不相邻的两个点置换, 无论哪一种, 这个都可以cover.  
     }  
     prev = root;  
     recoverTreeHelper(root->right, prev, first, second);  
   }  
 };  
   
 class Solution {  
 public:  
   //Version 3: Morris tree, inorder traversal  
   void recoverTree(TreeNode *root) {  
     TreeNode *cur = root, *prev = NULL;  
     TreeNode *first = NULL, *second = NULL, *last = NULL;  
     while (cur) {  
       if (cur->left == NULL) {  
         compare(last, cur, first, second);  
         last = cur;  
         cur = cur->right;  
       } else {  
         prev = cur->left;  
         while (prev->right != NULL && prev->right != cur) {  
           prev = prev->right;            
         }  
   
         if (prev->right == NULL) {  
           prev->right = cur;  
           cur = cur->left;  
         } else {  
           compare(last, cur, first, second);  
           last = cur;  
           prev->right = NULL;  
           cur = cur->right;  
         }  
       }  
     }  
     swap(first->val, second->val);  
   }  
   
   void compare(TreeNode *last, TreeNode *cur, TreeNode *&first, TreeNode *&second) {  
     if (last && last->val > cur->val) {  
       if (!first) first = last;  
       second = cur;  
     }  
   }  
 };  
   

Unique Binary Search Trees II

来源:Leetcode

原帖:http://oj.leetcode.com/problems/unique-binary-search-trees-ii/

题目:
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
 For example,
 Given n = 3, your program should return all 5 unique BST's shown below.
 1         3     3      2      1
  \         /     /       / \       \
   3     2     1      1   3      2
  /      /       \                      \
 2     1         2                    3

代码:
 class Solution {  
 public:  
   vector<TreeNode*> generateTrees(int n) {  
     return generateTreesHelper(1, n);  
   }  
   
   vector<TreeNode*> generateTreesHelper(int start, int end) { // 1...n, left = 1, right = n  
     vector<TreeNode*> res;  
     if (start > end) {  
       res.push_back(NULL);  
       return res;  
     }  
     for (int k = start; k <= end; k++) { // root starts from k; 拆分成不同left, right subtree  
       auto leftTrees = generateTreesHelper(start, k - 1);  
       auto rightTrees = generateTreesHelper(k + 1, end);  
       for (int i = 0; i < leftTrees.size(); i++) {  
         for (int j = 0; j < rightTrees.size(); j++) {  
           TreeNode* root = new TreeNode(k);  
           root->left = leftTrees[i]; // concatenate into left or right  
           root->right = rightTrees[j];  
           res.push_back(root);  
         }  
       }  
     }  
     return res;  
   }  
 };  

156 Binary Tree Upside Down

来源:Leetcode

原帖:https://leetcode.com/problems/binary-tree-upside-down/

题目:
Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the same parent node) or empty, flip it upside down and turn it into a tree where the original right nodes turned into left leaf nodes. Return the new root.
For example:
Given a binary tree {1,2,3,4,5},
        1
       / \
      2   3
     / \
    4   5
return the root of the binary tree [4,5,2,#,#,3,1].
       4
      / \
     5   2
        / \
       3   1

代码:
 /**   
  * 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 *upsideDownBinaryTree(TreeNode *root) {  
     if(!root || (!root->left && !root->right))   
       return root;  
     TreeNode * parent = upsideDownBinaryTree(root->left);  
     root->left->left = root->right;//because parameter could be NULL, so parent->left does not make sense.  
     root->left->right = root;   
     root->left = NULL;  
     root->right = NULL;  
     return parent;  
   }  
 };  
   
 class Solution {  
 public:  
   TreeNode* upsideDownBinaryTree(TreeNode* root) {  
     if (!root) return NULL;  
     TreeNode* p = root, *parent = NULL, *parentRight = NULL;  
     while (p) {  
       TreeNode* left = p->left;  
       p->left = parentRight;  
       parentRight = p->right;  
       p->right = parent;  
       parent = p;  
       p = left;  
     }  
     return parent;  
   }  
 };  

Validate Binary Search Tree

来源:Leetcode

原帖:http://oj.leetcode.com/problems/validate-binary-search-tree/

题目:
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees.
Definition:
all elements in its left subtree are less-or-equal to the node (<=),  and all the elements in its right subtree are greater than the node (>).

代码:
 /**  
  * Definition for binary treevalid  
  * struct TreeNode {  
  *   int val;  
  *   TreeNode *left;  
  *   TreeNode *right;  
  *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
  * };  
  */  
 class Solution {  
 public:  
   //Pre-order traversal (lower bound + higher bound)  
   bool isValidBST(TreeNode *root) {  
     TreeNode *min = NULL, *max = NULL;  
     return isValidBSTHelper(root, min, max);  
   }  
   
   bool isValidBSTHelper(TreeNode *node, TreeNode* min, TreeNode* max) {  
     if (!node) return true;  
     if ((min && node->val <= min->val) || (max && node->val >= max->val)) return false;  
     return isValidBSTHelper(node->left, min, node)   
       && isValidBSTHelper(node->right, node, max);  
   }  
 };  
   
 class Solution {  
 public:   
   //Inorder traversal & lower bound  
   bool isValidBST(TreeNode *root) {  
     TreeNode* min = NULL;  
     return isValidBSTHelper(root, min);  
   }  
   
   bool isValidBSTHelper(TreeNode *node, TreeNode* &min) {  
     if (!node) return true;  
     if (node->left && !isValidBSTHelper(node->left, min)) return false;        
     if (min && node->val <= min->val) return false;        
     min = node;  
     if (node->right && !isValidBSTHelper(node->right, min)) return false;        
     return true;  
   }  
 };  

Sum Root to Leaf Numbers

来源:Leetcode

原帖:https://oj.leetcode.com/problems/sum-root-to-leaf-numbers/

题目:
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers.
For example,
   1
  / \
 2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.

代码:
 /**  
  * 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) {  
     int sum = 0;  
     sumNumbersHelper(root, 0, sum);  
     return sum;  
   }  
     
   void sumNumbersHelper(TreeNode *node, int num, int &sum) {  
     if (!node) return;  
     num = num * 10 + node->val;  
     if (!node->left && !node->right) {   
       sum += num;  
       return;  
     }  
     sumNumbersHelper(node->left, num, sum);  
     sumNumbersHelper(node->right, num, sum);  
   }  
 };  
   
 class Solution {  
 public:  
   int sumNumbers(TreeNode *root) {  
     if (!root) return 0;      
     int res = 0;  
     queue<pair<TreeNode*, int> > q;  
     q.push(make_pair(root, 0));  
     while (!q.empty()) {  
       TreeNode *node = q.front().first;  
       int sum = q.front().second * 10 + node->val;  
       q.pop();  
       if (!node->left && !node->right) {  
         res += sum;  
         continue;  
       }       
       if (node->left) q.push(make_pair(node->left, sum));          
       if (node->right) q.push(make_pair(node->right, sum));  
     }  
     return res;  
   }  
 };  

Path Sum II

来源:Leetcode

原帖:https://oj.leetcode.com/problems/path-sum-ii/

题目:
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
return
[
   [5,4,11,2],
   [5,8,4,5]
]

代码:
 /**  
  * 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> > pathSum(TreeNode *root, int sum) {  
     vector<vector<int> > res;  
     vector<int> path;  
     pathSumHelper(root, sum, path, res);  
     return res;  
   }  
   
   void pathSumHelper(TreeNode *root, int sum, vector<int> &path, vector<vector<int>> &res) {  
     if (!root) return;  
     if (!root->left && !root->right) {  
       if (sum == root->val) {  
         path.push_back(root->val); //  
         res.push_back(path);  
         path.pop_back(); //  
       }  
       return;  
     }      
     path.push_back(root->val);  
     pathSumHelper(root->left, sum - root->val, path, res);  
     pathSumHelper(root->right, sum - root->val, path, res);  
     path.pop_back();  
   }  
 };