代码随想录算法训练营第十六天| 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

找树左下角的值

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 }

 

posted @ 2023-06-24 10:55  博二爷  阅读(2)  评论(0编辑  收藏  举报