代码随想录day18

513. 找树左下角的值

 1 class Solution {
 2 public:
 3     int findBottomLeftValue(TreeNode* root) {
 4         //创建result用于存储结果
 5         int result = 0;
 6         queue<TreeNode*> que;
 7         if (root != nullptr) que.push(root); 
 8         //只有根节点的情况直接返回根节点的值
 9         if (root->left == nullptr && root->right == nullptr)    return root->val; 
10         while (!que.empty()){
11             int size = que.size();
12             //创建标志位
13             int flag = 0;
14             while (size--){
15                 TreeNode* node = que.front();
16                 que.pop(); 
17                 if (node->left != nullptr && node->left->left == nullptr && node->left->right == nullptr){
18                     if (flag == 1){
19 
20                     } else {//每一层最左边叶子的值被取出后,flag置位1
21                         result = node->left->val;
22                         flag = 1;
23                     }
24                 } else if (node->left == nullptr && node->right != nullptr && node->right->left == nullptr && node->right->right == nullptr){
25                     result = node->right->val;
26                 }
27                 if (node->left) que.push(node->left);
28                 if (node->right) que.push(node->right);
29             }
30         } 
31         return result;
32     }  
33 };

卡哥迭代法:

 1 class Solution {
 2 public:
 3     int findBottomLeftValue(TreeNode* root) {
 4         //创建result用于存储结果
 5         int result = 0;
 6         queue<TreeNode*> que;
 7         if (root != nullptr) que.push(root); 
 8         while (!que.empty()){
 9             int size = que.size();
10             for (int i = 0; i < size; i++){
11                 TreeNode* node = que.front();
12                 que.pop(); 
13                 if (i == 0) result = node->val;
14                 if (node->left) que.push(node->left);
15                 if (node->right) que.push(node->right);
16             }
17         } 
18         return result;
19     }  
20 };

*112. 路径总和

 1 class Solution {
 2 private:
 3     bool traversal(TreeNode* cur, int count){
 4         //遇到叶子结点,并且计数器为0
 5         if (!cur->left && !cur->right && count == 0) return true;
 6         if (!cur->left && !cur->right) return false;
 7         //处理左子树
 8         if (cur->left){
 9             count -= cur->left->val;
10             if (traversal(cur->left, count)) return true;
11             count += cur->left->val;
12         }
13         //处理右子树
14         if (cur->right){
15             count -= cur->right->val;
16             if (traversal(cur->right, count)) return true;
17             count += cur->right->val;
18         }
19         return false;
20     }
21 public:
22     bool hasPathSum(TreeNode* root, int targetSum) {
23         if (root == nullptr) return false;
24         return traversal(root, targetSum - root->val);
25     }
26 };

*113. 路径总和 II

 1 class Solution {
 2 private:
 3     vector<vector<int>> result;
 4     vector<int> path;
 5 
 6     void traversal(TreeNode* cur, int count){
 7         //遇到了叶子节点并且满足和为sum的条件
 8         if (!cur->left && !cur->right && count == 0){
 9             result.push_back(path);
10             return;
11         }
12         //没有找到合适的路径到达叶子结点
13         if (!cur->left && !cur->right) return;
14 
15         //遍历左子树
16         if (cur->left){
17             path.push_back(cur->left->val);
18             count -= cur->left->val;
19             traversal(cur->left, count);
20             count += cur->left->val;
21             path.pop_back();
22         }
23         //遍历右子树
24         if (cur->right){
25             path.push_back(cur->right->val);
26             count -= cur->right->val;
27             traversal(cur->right, count);
28             count += cur->right->val;
29             path.pop_back();
30         }
31         return ;
32     }
33 public:
34     vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
35         result.clear();
36         path.clear();
37         if (root == nullptr) return result;
38         path.push_back(root->val);
39         traversal(root, targetSum - root->val);
40         return result;
41     }
42 };

 *106. 从中序与后序遍历序列构造二叉树

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

 1 class Solution {
 2 public:
 3 
 4     TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {
 5         if (postorder.size() == 0) return nullptr;
 6 
 7         // 后序遍历数组的最后一个元素,就是当前的中间结点
 8         int rootValue = postorder[postorder.size() - 1];
 9         TreeNode* root = new TreeNode(rootValue);
10 
11         // 叶子结点
12         if (postorder.size() == 1) return root;
13 
14         // 找到中序遍历的切割点
15         int delimiterIndex;
16         for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {
17             if (inorder[delimiterIndex] == rootValue) break;
18         }
19 
20         //切割中序数组
21         //左闭右开区间:[0, delimiterIndex]
22         vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
23         //[delimiterIndex + 1, end]
24         vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end());
25 
26         // posterorder 舍弃末尾元素
27         postorder.resize(postorder.size() - 1);
28 
29         // 切割后序数组
30         // 依然左闭右开, 注意这里使用了左中序数组大小作为切割点
31         // [0, leftInorder.size()]
32         vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
33         // [leftInorder.size(), end]
34         vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
35 
36         root->left = traversal(leftInorder, leftPostorder);
37         root->right = traversal(rightInorder, rightPostorder);
38 
39         return root;
40     }
41 
42     TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
43         if (inorder.size() == 0 || postorder.size() == 0) return nullptr;
44         return traversal(inorder, postorder);
45     }
46 };

*105. 从前序与中序遍历序列构造二叉树

 1 class Solution {
 2 private:
 3         TreeNode* traversal (vector<int>& inorder, int inorderBegin, int inorderEnd, vector<int>& preorder, int preorderBegin, int preorderEnd) {
 4         if (preorderBegin == preorderEnd) return NULL;
 5 
 6         int rootValue = preorder[preorderBegin]; // 注意用preorderBegin 不要用0
 7         TreeNode* root = new TreeNode(rootValue);
 8 
 9         if (preorderEnd - preorderBegin == 1) return root;
10 
11         int delimiterIndex;
12         for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {
13             if (inorder[delimiterIndex] == rootValue) break;
14         }
15         // 切割中序数组
16         // 中序左区间,左闭右开[leftInorderBegin, leftInorderEnd)
17         int leftInorderBegin = inorderBegin;
18         int leftInorderEnd = delimiterIndex;
19         // 中序右区间,左闭右开[rightInorderBegin, rightInorderEnd)
20         int rightInorderBegin = delimiterIndex + 1;
21         int rightInorderEnd = inorderEnd;
22 
23         // 切割前序数组
24         // 前序左区间,左闭右开[leftPreorderBegin, leftPreorderEnd)
25         int leftPreorderBegin =  preorderBegin + 1;
26         int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBegin; // 终止位置是起始位置加上中序左区间的大小size
27         // 前序右区间, 左闭右开[rightPreorderBegin, rightPreorderEnd)
28         int rightPreorderBegin = preorderBegin + 1 + (delimiterIndex - inorderBegin);
29         int rightPreorderEnd = preorderEnd;
30 
31         root->left = traversal(inorder, leftInorderBegin, leftInorderEnd,  preorder, leftPreorderBegin, leftPreorderEnd);
32         root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);
33 
34         return root;
35     }
36 
37 public:
38     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
39         if (inorder.size() == 0 || preorder.size() == 0) return NULL;
40 
41         // 参数坚持左闭右开的原则
42         return traversal(inorder, 0, inorder.size(), preorder, 0, preorder.size());
43     }
44 };
posted @ 2022-10-12 16:38  aijiajia0509  阅读(25)  评论(0)    收藏  举报