(2015/11/18)java
LeetCode 96 Unique Binary Search Trees:(Medium)算法
1)若用95題的方法遞歸就會超時。數組
2)參考《算法導論》第15章,採用自底向上的方法實現動態規劃算法。post
題目:ui
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?spa
1)binary search trees:二叉搜索樹,性質:結點x,其左子樹中結點的關鍵字小於x的關鍵字,右子樹中結點的關鍵字大於x的關鍵字。指針
2)對其中序遍歷,關鍵字單調遞增。code
分析:排序
1)一組單調遞增的值,能構成多少棵結構上獨一無二的二叉搜索樹,只和這組值的個數有關,和值無關。遞歸
代碼:
class Solution {
public:
int numTrees(int n) {
vector<int> numsubtrees(n + 1, 1); //以結點個數爲下標,存儲可構成的樹的個數
for(int j = 1; j <= n; j++){ //j表明本次循環,結點總個數
int q = 0; //j個結點可構成多少棵樹
for(int i = 1; i <= j; i++) //j個結點中以第i個結點爲根構造子樹
q += numsubtrees[i - 1] * numsubtrees[j - i]; //左子樹個數*右子樹個數
numsubtrees[j] = q;
}
return numsubtrees[n];
}
};
LeetCode 98 Validate Binary Search Tree:(Medium)
1)中序遍歷二叉樹,再判斷遍歷後的值序列是否單調遞增。
LeetCode 103 Binary Tree Zigzag Level Order Traversal:(Medium)
1)使用隊列,棧,再作個標記便可。
(2015/11/19)
LeetCode 105 Construct Binary Tree from Preorder and Inorder Traversal:(Medium)
根據先序遍歷和中序遍歷構建二叉樹。結點的關鍵字不重複。
1)Memory Limit Exceeded
每次遞歸都建立存儲子樹結點關鍵字的容器,會內存超出。
2)可分別用兩個int變量,在preorder和inorder中指示一顆子樹的結點集合。(集合的起始位置和最後一個元素後一個位置)
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 || inorder.size() == 0) return NULL;
return myBuildTree(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode *myBuildTree(vector<int> &preorder, int prebegin, int preend, \
vector<int> &inorder, int inbegin, int inend){
int rootval = preorder[prebegin];//根節點
//左子樹中序
int linbegin = inbegin, linend = inbegin;
while(linend < inend && inorder[linend] != rootval) linend++;
//右子樹中序
int rinbegin = linend + 1, rinend = inend;
//左子樹先序
int lprebegin = prebegin + 1, lpreend = prebegin + 1 + linend - linbegin;
//右子樹先序
int rprebegin = lpreend, rpreend = lpreend + rinend - rinbegin;
TreeNode *root = new TreeNode(rootval);
if(lpreend - lprebegin != 0) root->left = myBuildTree(preorder, lprebegin, lpreend, inorder, linbegin, linend);
else root->left = NULL;
if(rpreend - rprebegin != 0) root->right = myBuildTree(preorder, rprebegin, rpreend, inorder, rinbegin, rinend);
else root->right = NULL;
return root;
}
};
(2015/11/21)
LeetCode 169 Majority Element:(Easy)
1)排序。
LeetCode 106 Construct Binary Tree from Inorder and Postorder Traversal:(Medium)
根據中序和後續遍歷構造二叉樹
1)同105。
LeetCode 108 Convert Sorted Array to Binary Search Tree:(Medium)
將一個升序排列的數組,構形成一顆高度平衡二叉樹。
1)高度平衡二叉樹:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。
2)遞歸:找出合理的根結點(數組中間的元素做爲根結點的值),遞歸構造左右子樹。(速度較慢)
LeetCode 113Path Sum II:(Medium)
1)二叉樹的深度優先遍歷。
2)用到了vector的pop_back操做。
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans;
vector<int> veci;
if(root != NULL) DFS(root, sum, 0, veci, ans);
return ans;
}
void DFS(TreeNode *root, int sum, int now, vector<int> veci, \
vector<vector<int>> &ans){
veci.push_back(root->val);
now += root->val;
if(root->left == NULL && root->right == NULL && now == sum)
ans.push_back(veci);
if(root->left != NULL) DFS(root->left, sum, now, veci, ans);
if(root->right != NULL) DFS(root->right, sum, now, veci, ans);
veci.pop_back();
return;
}
};
(2015/11/22)
LeetCode 114Flatten Binary Tree to Linked List:(Medium)
題目:把一顆二叉樹按先序遍歷的結點順序,改成一個相似於鏈表的結構。
個人方法:按先序遍歷的順序,把結點放入一個容器中。(須要不少額外的空間存儲結點指針,有點浪費)
更好的方法:參考:https://leetcode.com/discuss/30719/my-short-post-order-traversal-java-solution-for-share
1)若以相反的順序對結點進行遍歷(右子樹->左子樹->根),一個結點一個結點往上修改,就只須要一個指針存儲上一個結點的指針便可。
class Solution {public: TreeNode *prev; void flatten(TreeNode* root) { if(root == NULL) return; flatten(root->right); flatten(root->left); root->right = prev; root->left = NULL; prev = root; } };