(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)
题目:把一颗二叉树按先序遍历的结点顺序,改为一个类似于链表的结构。
我的方法:按先序遍历的顺序,把结点放入一个容器中。(需要很多额外的空间存储结点指针,有点浪费)
更好的方法:参考:
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; } };