代码随想录算法训练营第十六天| 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树
找树左下角的值
1,层序遍历,较为简单:
1 int findBottomLeftValue_simple(TreeNode* root) { 2 int result = 0; 3 if (!root) return result; 4 queue<TreeNode*> selected; 5 selected.push(root); 6 7 while (!selected.empty()) 8 { 9 int i = selected.size(); 10 result = selected.front()->val; 11 while (i != 0) 12 { 13 auto cur_ = selected.front(); 14 selected.pop(); 15 16 if (cur_->left) selected.push(cur_->left); 17 if (cur_->right) selected.push(cur_->right); 18 i--; 19 } 20 } 21 return result; 22 }
2,递归法:
注意:终止条件是叶子节点,如果是叶子节点,就判断他是不是最大的深度,如果是,那么就更新它的值
而且需要先左后右,这样就不会导致被替换
代码:
1 void findBottom_cur(TreeNode* node, int &height, int& maxHeight, int& result) 2 { 3 if (!node) return ; 4 5 6 //获得左叶子的值,需要判断它是否是最底层 7 if (!node->left && !node->right) 8 { 9 if (height > maxHeight) 10 { 11 result = node->val; 12 maxHeight = height; 13 } 14 15 return; 16 } 17 18 height += 1; 19 findBottom_cur(node->left, height, maxHeight, result); 20 height -= 1; 21 height += 1; 22 findBottom_cur(node->right, height,maxHeight, result); 23 height -= 1; 24 25 } 26 int findBottomLeftValue(TreeNode* root) { 27 int result = 0; 28 int height = 0; 29 int maxHeight = INT_MIN; 30 findBottom_cur(root, height, maxHeight, result); 31 return result;; 32 }
路径总和
思路:注意回溯,可以想到找出所有路径的模板方案
迭代法
1 bool hasPathSum_complate(TreeNode* root, int targetSum) { 2 if (!root) return false; 3 4 stack<TreeNode*>selected; 5 stack<vector<int>> vals; 6 vals.push({ root->val }); 7 selected.push(root); 8 while (!selected.empty()) 9 { 10 auto curNode = selected.top(); selected.pop(); 11 auto curVals = vals.top(); vals.pop(); 12 13 if (!curNode->left && !curNode->right) 14 { 15 if (curNode->val == 2) 16 { 17 cout << "a"; 18 } 19 int sum = 0; 20 for (int i = 0; i < curVals.size(); i++) 21 { 22 sum += curVals[i]; 23 } 24 if (sum == targetSum) 25 { 26 return true; 27 } 28 } 29 30 if (curNode->left) { 31 selected.push(curNode->left); 32 33 curVals.push_back(curNode->left->val); 34 vals.push(curVals); 35 curVals.pop_back(); 36 } 37 38 if (curNode->right) 39 { 40 selected.push(curNode->right); 41 curVals.push_back(curNode->right->val); 42 vals.push(curVals); 43 curVals.pop_back(); 44 } 45 } 46 47 return false; 48 }
递归法
1 bool hasPathSum_cursor(TreeNode* node, int& count) 2 { 3 if (!node) return false; 4 5 count -= node->val; 6 if (!node->left && !node->right && count ==0) 7 { 8 return true; 9 } 10 if (!node->left && !node->right && count != 0) 11 { 12 return false; 13 } 14 15 //左节点 16 bool left = false; 17 bool right = false; 18 if (node->left) 19 { 20 left = hasPathSum_cursor(node->left, count); 21 count += node->left->val; 22 } 23 if (node->right) 24 { 25 right = hasPathSum_cursor(node->right, count); 26 count += node->right->val; 27 } 28 29 return right || left; 30 } 31 32 bool hasPathSum(TreeNode* root, int targetSum) { 33 if (!root) return false; 34 35 return hasPathSum_cursor(root, targetSum); 36 }
找到所有的路径
迭代法:
1 vector<vector<int>> pathSum_complate(TreeNode* root, int targetSum) { 2 vector<vector<int>> result; 3 if (!root) return result; 4 stack<TreeNode*> selected; 5 stack<vector<int>> vals; 6 7 selected.push(root); 8 vals.push({ root->val }); 9 while (!selected.empty()) 10 { 11 auto cur_ = selected.top(); selected.pop(); 12 auto val_ = vals.top(); vals.pop(); 13 14 if (!cur_->left && !cur_->right) 15 { 16 int sum = 0; 17 for (int i = 0; i < val_.size(); i++) 18 { 19 sum += val_[i]; 20 } 21 if (sum == targetSum) 22 { 23 result.push_back(val_); 24 } 25 } 26 27 if (cur_->left) 28 { 29 selected.push(cur_->left); 30 val_.push_back(cur_->left->val); 31 vals.push(val_); 32 val_.pop_back(); 33 } 34 if (cur_->right) 35 { 36 selected.push(cur_->right); 37 val_.push_back(cur_->right->val); 38 vals.push(val_); 39 val_.pop_back(); 40 } 41 } 42 43 return result; 44 }
递归法:
1 //递归法 2 void pathSum_cursor(TreeNode* node, int& count,vector<int>& vals, vector<vector<int>>& result) 3 { 4 if (!node) return; 5 6 count -= node->val; 7 vals.push_back(node->val); 8 if (!node->left && !node->right && count == 0) 9 { 10 result.push_back(vals); 11 } 12 13 if (node->left) 14 { 15 pathSum_cursor(node->left, count, vals, result); 16 count += node->left->val; 17 vals.pop_back(); 18 } 19 if (node->right) 20 { 21 pathSum_cursor(node->right, count, vals, result); 22 count += node->right->val; 23 vals.pop_back(); 24 } 25 } 26 27 vector<vector<int>> pathSum(TreeNode* root, int targetSum) { 28 vector<vector<int>> result; 29 if (!root) return result; 30 vector<int> val; 31 pathSum_cursor(root, targetSum, val, result); 32 return result; 33 }
从中序与后序遍历序列构造二叉树
难点:
1,后序的最后一个是节点,然后分割中序,中序的左的长度,是后序左的长度(一定不要自己试图用index分割,会导致outmerory)
代码:
1 void print_vector(const vector<int> target) 2 { 3 for (int i = 0; i < target.size(); i++) 4 { 5 cout << target[i]<<" "; 6 } 7 cout << endl; 8 } 9 10 TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) 11 { 12 if (postorder.size() == 0 || postorder.size()==0) return NULL; 13 14 //如果inorder==null,应该怎么处理? 15 int curVal = postorder[postorder.size() - 1]; 16 TreeNode* curNode = new TreeNode(curVal); 17 18 // 叶子节点 !!!! 19 //if (postorder.size() == 1) return curNode; 20 21 vector<int> leftInorder, rightInorder; 22 int indexInorder = 0; 23 for (int i = 0; i < inorder.size(); i++) 24 { 25 if (inorder[i] == curVal) 26 { 27 indexInorder = i; 28 break; 29 } 30 } 31 leftInorder = vector<int>(inorder.begin(), inorder.begin() + indexInorder); 32 rightInorder = vector<int>(inorder.begin() + indexInorder+1, inorder.end()); 33 //print_vector(leftInorder); print_vector(rightInorder); 34 35 36 // !! 用的是 中序的左边的size(); 37 //根据中序中左边的最后一个来进行拆分 38 vector<int> leftPostorder, rightPostorder; 39 postorder.resize(postorder.size() - 1); 40 41 leftPostorder = vector<int>(postorder.begin(), postorder.begin() + leftInorder.size()); 42 rightPostorder = vector<int>(postorder.begin() + leftInorder.size(), postorder.end()); 43 //print_vector(leftPostorder); print_vector(rightPostorder); 44 45 curNode->left = buildTree(leftInorder, leftPostorder); 46 curNode->right = buildTree(rightInorder, rightPostorder); 47 48 return curNode; 49 } 50 51 52 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { 53 if (inorder.size() == 0 || postorder.size() == 0) return NULL; 54 return traversal(inorder, postorder); 55 }