【leetcode】42.接雨水 (单调栈等多种解法,java实现)

本文介绍了LeetCode 42题——接雨水问题,通过四种方法来解决,包括暴力求解、动态规划、单调栈应用以及双指针法,并提供了详细的解题思路和Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

406. 根据身高重建队列

难度中等442

假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

注意:
总人数少于1100人。

示例

输入:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

输出:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

📖 文字题解

方法 1:暴力

直观想法

直接按问题描述进行。对于数组中的每个元素,我们找出下雨后水能达到的最高位置,等于两边最大高度的较小值减去当前高度的值。

算法

  • 初始化 ans=0
  • 从左向右扫描数组:
    • 初始化max_left=0 和 max_right=0
    • 从当前元素向左扫描并更新:
      • max_left=max(max_left,height[j])
    • 从当前元素向右扫描并更新:
      • max_right=max(max_right,height[j])
    • 将min(max_left,max_right)−height[i] 累加到ans
int trap(vector<int>& height)
{
   
   
    int ans = 0;
    int size = height.size();
    for (int i = 1; i < size - 1; i++) {
   
   
        int max_left = 0, max_right = 0;
        for (int j = i; j >= 0; j--) {
   
    //Search the left part for max bar size
            max_left = max(max_left, height[j]);
        }
        for (int j = i; j < size; j++) {
   
    //Search the right part for max bar size
            max_right = max(max_right, height[j]);
        }
        ans += min(max_left, max_right) - height[i];
    }
    return ans;
}

复杂性分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)。数组中的每个元素都需要向左向右扫描。

  • 空间复杂度 O(1)的额外空间。


方法 2:动态编程

直观想法

在暴力方法中,我们仅仅为了找到最大值每次都要向左和向右扫描一次。但是我们可以提前存储这个值。因此,可以通过动态编程解决。

这个概念可以见下图解释:

trapping_rain_water.png

算法

  • 找到数组中从下标 i 到最左端最高的条形块高度 left_max。
  • 找到数组中从下标 i 到最右端最高的条形块高度right_max。
  • 扫描数组height并更新答案:
    • 累加 KaTeX parse error: Expected '}', got '_' at position 15: \min(\text{max_̲left}[i],\text{… 到 ans 上
int trap(vector<int>& height)
{
   
   
	if(height == null)
		return 0;
    int ans = 0;
    int size = height.size();
    vector<int> left_max(size), right_max(size);
    left_max[0] = height[0];
    for (int i = 1; i < size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值