42. Trapping Rain Water && Binary Tree Preorder\Postorder\Inorder Traversal

42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

img
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. **Thanks Marcos**for contributing this image!

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
解题思路

该题有多种解法,参见trapping-rain-water/solution

此处简述两种比较简单的解法。

法1:一开始想到的很直接的方法,是遍历所有的纵坐标,求出每一行的储水量求和,但由于每一行都需要遍历一次,复杂度为O(N^2)

法2:求出每个横坐标的左右两边的最高点(包括自己),而在该点的储水量就等于两边最高点中较小的一个减去该点自身的高度。

  • 具体地,使用left_maxright_max两个向量分别存储每个横坐标左、右的最高点;
  • 每个横坐标的储水量为:min(left_max[i],right_max[i]) - height[i]
  • 代码如下:
程序代码
class Solution {
public:
    int trap(vector<int>& height) {
        //对每个横坐标分别找左边和右边的最大值,该点的储水量就是min(left_max, right_max)-height
        int n = height.size(), res = 0;
        if (!n) return res;
        vector<int> left_max(n, height[0]), right_max(n, height[n-1]);
        for (int i = 1; i < n; i++){
            left_max[i] = max(left_max[i-1], height[i]);
            right_max[n - i - 1] = max(right_max[n - i], height[n - i - 1]);
        }
        for (int i = 0; i < n; i++)
            res += min(left_max[i], right_max[i]) - height[i];
        return res;
    }
};

144. Binary Tree Preorder Traversal(非递归前序遍历)

Given a binary tree, return the preorder traversal of its nodes’ values.

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [1,2,3]

Follow up: Recursive solution is trivial, could you do it iteratively?

解题思路

按照“中-左-右” 的遍历顺序,应该是先走到根,然后分别走左右子节点;而走左节点的时候,如果有孩子,则应该先走完孩子再回去走根的右节点。

大概地模拟一遍,显然可以用栈stack来模拟这个过程,每次获取栈顶节点的值,然后弹出,并且依次加入该节点的右节点、左节点,直到栈为空为止。

程序代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        if (root) s.push(root);
        while(!s.empty()){
            TreeNode * t = s.top();
            s.pop();
            res.push_back(t->val);
            if (t->right) s.push(t->right);
            if (t->left) s.push(t->left);
        }
        return res;
    }
};

145. Binary Tree Postorder Traversal(非递归后序遍历)

Given a binary tree, return the postorder traversal of its nodes’ values.

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [3,2,1]

Follow up: Recursive solution is trivial, could you do it iteratively?

解题思路

按照“左-右-中” 的遍历顺序,同样大概地模拟后,应该要跟前一题一样,使用栈。

并且,我们在模拟中应该会发现,无法直接给出正确的顺序(不知道当前节点下面到底有多少节点),但是我们可以知道,当前节点肯定是最后一个,也就是我们可以给出倒序。

接下来的思路同前序遍历时相同,每次获取栈顶节点的值,然后弹出,并且依次加入该节点的左节点、右节点,直到栈为空为止。

程序代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
#include <algorithm>  //std::reverse
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        if (root) s.push(root);
        //倒序放入
        while(!s.empty()){
            TreeNode * t = s.top();
            s.pop();
            res.push_back(t->val);
            if (t->left) s.push(t->left);
            if (t->right) s.push(t->right);
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

94. Binary Tree Inorder Traversal(非递归中序遍历)

Given a binary tree, return the inorder traversal of its nodes’ values.

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [1,3,2]

Follow up: Recursive solution is trivial, could you do it iteratively?

解题思路

模拟后发现,我们会先找到最深的左节点,然后对每个左节点,寻找其右孩子,并且把右孩子的所有左孩子都加入栈中即可。

程序代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector <int> res;
        TreeNode * t = root;
        stack<TreeNode *> s;
        while (t){
            s.push(t);
            t = t->left;
        }
        while(!s.empty()){
            TreeNode * e = s.top();
            s.pop();
            res.push_back(e->val);
            if (e->right){
                TreeNode * x = e->right;
                while (x){
                    s.push(x);
                    x = x->left;
                }
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36153312/article/details/82020681