classSolution { public: TreeNode* trimBST(TreeNode* root, int L, int R){ if(!root) returnnullptr; // if the root is less than L, then the root itself and all the nodes in its left subtree will be discarded if(root->val < L) returntrimBST(root->right, L, R); // if the root is greater than R, then the root itself and all the nodes in its right subtree will be discarded if(root->val > R) returntrimBST(root->left, L, R); // if the root is in [L, R], then call trim on its left and right subtree recursively. root->left = trimBST(root->left, L, R); root->right= trimBST(root->right,L, R); return root; } };
classSolution { public: TreeNode* sortedListToBST(ListNode* head){ auto list = vector<int>{}; // copy the linked list into an array while(head) { list.push_back(head->val); head = head->next; }
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ classSolution { public: vector<TreeNode*> generateTrees(int n){ if(n == 0) return {}; returngenerateTrees(1, n + 1); }
vector<TreeNode*> generateTrees(int first, int last) { // recursion stop condition // if first == last, the range is empty, just push a // nullptr into the trees vector. if(!(first < last)) return {nullptr}; auto trees = vector<TreeNode*>{}; // pick up a node to be the root for(int i = first; i < last; ++i) { auto leftTrees = generateTrees(first, i); auto rightTrees = generateTrees(i + 1, last);
// build trees for(auto leftRoot : leftTrees) { for(auto rightRoot : rightTrees) { auto curTree = new TreeNode{i}; curTree->left = leftRoot; curTree->right = rightRoot; trees.push_back(curTree); } } }
classSolution { public: intnumTrees(int n){ returnnumTrees(1, n + 1); }
intnumTrees(int first, int last) { // recursion stop condition // the range is empty, we can build no tree from it if(!(first < last)) return1;
auto curNums = 0; // pick a node as root for(int i = first; i < last; ++i) { auto leftNums = numTrees(first, i); auto rightNums = numTrees(i + 1, last);
curNums += leftNums * rightNums; }
return curNums; } };
验证BST
验证BST本体
LC98 Validate Binary Search Tree 思路:这个题不能简单的通过前序遍历递归判断一个节点是否 大于左孩子 && 小于右孩子。二叉搜索树要求一个节点的右子树的所有节点都比该节点大,一个节点的左孩子的所有节点都比该节点小。不是简单的和【左孩子】【右孩子】的关系。正确的思路:中序遍历,记录前值,比较大小,如果后面的数不比前面大,二叉搜索树不正确。这个题坑比较多,前值不能简单的初始化设置成INT_MIN,因为他测试用例里有INT_MIN。所以得设置个isFirstElement的flag来判断前值是否已经设置好。或者用容量更大的int64_t,省去很多流程控制语句。
auto back = *(last - 1); auto cmp = [back](auto x){return x < back;}; if(is_partitioned(first, last, cmp)) { auto point = partition_point(first, last, cmp); returnis_bbst(first, point) && is_bbst(point, last - 1); }
classSolution { public: boolverifyPostorder(vector<int>& postorder){ returnverifyPostorder(postorder.begin(), postorder.end()); } template<typename It> boolverifyPostorder(It first, It last) { //range is empty, nothing to check if(!(first < last)) returntrue; // postorder traversal squence must be partitioned by the // last element. --last; auto last_val = *last; auto cmp = [&last_val](auto x){ return x < last_val;}; if(!is_partitioned(first, last, cmp)) returnfalse; // find the partition point, the sequence could then be seperated // into its left and right subtrees' postorder traversal sequence auto leftTreeLast = partition_point(first, last, cmp); returnverifyPostorder(first, leftTreeLast) && verifyPostorder(leftTreeLast, last); } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: boolverifySequenceOfBST(vector<int> sequence){ if(sequence.empty() || sequence.size() <= 2) returntrue; return _verifySequenceOfBSTImpl(sequence.begin(), sequence.end()); } template<typename It> bool _verifySequenceOfBSTImpl(It first, It last){ if(distance(first, last)<=2) returntrue; auto back = last - 1; auto cmp = [&back](int x){return x<*back;}; if(is_partitioned(first, last, cmp)){ auto x = partition_point(first, last, cmp);//O(log(n)) return _verifySequenceOfBSTImpl(first, x) && _verifySequenceOfBSTImpl(x, last - 1); }elsereturnfalse;
//clear the state first = nullptr; last = nullptr;
return head; }
voidtreeToDoublyList_(Node* root) { if(!root) return; treeToDoublyList_(root->left); // if last is nullptr then this is the first node in the traversal if(!last) { //set first first = root; } else { // link root with the last node root->left = last; last->right = root; }
classSolution { public: voidflatten(TreeNode* root){ while(root) { // if there is no left subtree, continue to check its // right subtree if(!root->left) { root = root->right; continue; }
// replace its right subtree with its left subtree auto right = root->right; root->right = root->left; root->left = nullptr;
auto new_root = root->right; // move right to the end while(root->right) { root = root->right; }
// attach its right subtree there root->right = right;
classBSTIterator { private: stack<TreeNode*> m_stack; TreeNode* m_root; public: BSTIterator(TreeNode* root) :m_stack{} ,m_root{root} {} /** @return the next smallest number */ intnext(){ returninorder()->val; } /** @return whether we have a next smallest number */ boolhasNext(){ return m_root || !m_stack.empty(); }
classSolution { public: Node* inorderSuccessor(Node* node){ if(!node) returnnullptr; // if the node has a right ptr // we have to find the smallest node in its // right subtree if(node->right) { node = node->right; while(node->left) node = node->left; return node; }
// if the node has no right ptr // we have to find the first node that takes it as // left child. auto parent = node->parent; // if there is no such node, parent will move to the // parent of the root, which is nullptr, thus no worry while(parent && parent->left != node) { node = parent; parent = parent->parent; } return parent; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { public: TreeNode* inorderSuccessor(TreeNode* p){ if(p->right){ p = p->right; while(p->left) p = p->left; return p; }else{ while(p){ auto father = p->father; if(father && father->left == p) return father; p = father; } return p; } } };
// do inorder traversal on the tree while(true) { while(root) { stack.push_back(root); root = root->left; } if(stack.empty()) break; root = stack.back(); stack.pop_back(); // check if it is an inversion if(pre->val > root->val) { // log the inversions inversions.push_back(pre); inversions.push_back(root); } pre = root; root = root->right; }
// swap their value auto tmp = inversions.front()->val; inversions.front()->val = inversions.back()->val; inversions.back()->val = tmp; } };
classSolution { public: vector<int> findMode(TreeNode* root){ vector<int> res{}; vector<TreeNode*> stack{}; auto isFirstValue = true; auto val = 0; auto cnt = 0; auto max_cnt = 0; while(true) { while(root) { stack.push_back(root); root = root->left; }
if(stack.empty()) break;
root = stack.back(); stack.pop_back();
// if it is the first value in the tree if(isFirstValue) { val = root->val; cnt = 1; max_cnt = 1; isFirstValue = false; } // check if same value elseif(root->val == val) { ++cnt; } elseif(root->val != val) { //reset the counter val = root->val; cnt = 1; }
// check if the counter == max_cnt if(cnt == max_cnt) { res.push_back(root->val); } // we find a new max_count, clear the result elseif(cnt > max_cnt) { // update max_cnt max_cnt = cnt; // clear the res, we do not need them anymore res.clear(); // the new max res.push_back(root->val); }