2019独角兽企业重金招聘Python工程师标准>>>
(2015/11/18)
LeetCode 96 Unique Binary Search Trees:(Medium)
1)若用95题的方法递归就会超时。
2)参考《算法导论》第15章,采用自底向上的方法实现动态规划算法。
题目:
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
1)binary search trees:二叉搜索树,性质:结点x,其左子树中结点的关键字小于x的关键字,右子树中结点的关键字大于x的关键字。
2)对其中序遍历,关键字单调递增。
分析:
1)一组单调递增的值,能构成多少棵结构上独一无二的二叉搜索树,只和这组值的个数有关,和值无关。
代码:
class Solution {
public:
int numTrees(int n) {
vector 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& preorder, vector& inorder) {
if(preorder.size() == 0 || inorder.size() == 0) return NULL;
return myBuildTree(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode *myBuildTree(vector &preorder, int prebegin, int preend, \
vector &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> pathSum(TreeNode* root, int sum) {
vector> ans;
vector veci;
if(root != NULL) DFS(root, sum, 0, veci, ans);
return ans;
}
void DFS(TreeNode *root, int sum, int now, vector veci, \
vector> &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;
}
};