Leecode 42. 接雨水 经典面试题 双指针/动态规划

原题链接:Leecode 42. 接雨水

Leecode 42. 接雨水 经典面试题 双指针/动态规划_第1张图片
参考官方解法:Leecode 42. 接雨水官方解法

解法一:暴力 超时

class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        int ans=0;
        for(int i=1;i<n-1;i++)
        {
            int l=0,r=0;
            for(int j=i;j>=0;j--)
                l=max(l,height[j]);
            for(int j=i;j<n;j++)
                r=max(r,height[j]);
            ans+=min(l,r)-height[i];
        }
        return ans;
    }
};

解法二:利用数组存储每个点的左右最大高度

class Solution {
public:
    int trap(vector<int>& height) {
        int res = 0, n = height.size();
        vector<int> left(n);  // 表示每个位置左边的最高海拔
        vector<int> right(n); // 表示每个位置右边的最高海拔
        for (int i = n - 2; i > 0; i--) {
            right[i] = max(height[i + 1], right[i + 1]);
        }
        for (int i = 1; i < n; i++) {
            left[i] = max(height[i - 1], left[i - 1]);
        }
        for (int i = 0; i < n; i++) {
            res += max(min(right[i], left[i]) - height[i], 0);
        }
        return res;
    }
};

解法三:双指针

class Solution {
public:
    int trap(vector<int>& height) {
        int res = 0, n = height.size();
        int left = 0, right = n - 1; // 左,右指针,分别指向数组的两端
        int left_max=height[left]; // 表示左指针左边的最大值
        int right_max=height[right]; // 表示右指针右边的最大值
        while (left < right) {
            left_max = max(left_max, height[left]); // 更新左指针左边的最大值
            right_max = max(right_max, height[right]); // 更新右指针右边的最大值
            // 对于左指针left来说,left_max一定是它左边的最大值,但是right_max不一定是它右边的最大值,right_max指标只是它右边的某一个值
            // 如果left_max
            if (left_max < right_max) {
                res += left_max - height[left]; // left处的可接的雨水值等于它两侧的最小值left_max减去它本身的高度height[left]
                left++;         // 此时left处计算完成,left指针右移
            }
            // 对于右指针right来说,right_max一定是它右边的最大值,但是left_max不一定是它左边的最大值,left_max指标只是它左边的某一个值
            // 如果right_max<=left_max,那么对对于right位置来说,它两侧的最小值一定是right_max,
            if (right_max <= left_max) {
                res += right_max - height[right]; // right处的可接的雨水值等于它两侧的最小值right_max减去它本身的高度height[left]
                right--; // 此时right处计算完成,right指针右移
            }
        }
        return res;
    }
};

解法四:栈

class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        int ans=0;
        stack<int> st;
        for(int i=0;i<n;i++)
        {
            while(!st.empty() && height[i]>height[st.top()])
            {
                int tmp=height[st.top()];
                st.pop();
                if(st.empty())
                   break;
                int dis=i-st.top()-1;
                int h=min(height[st.top()],height[i])-tmp;
                ans=ans+dis*h;
            }
            st.push(i);
        }
        return ans;
    }
};

你可能感兴趣的:(Leetcode,c++,leetcode,指针,动态规划)