算法通关村——滑动窗口高频问题

本节我们继续来讲讲一道经典的滑动窗口问题,就是 leetCode11. 盛最多水的容器

在这里插入图片描述
本题目看似挺复杂的,其实只要把思路理清楚了,代码实现可以说是相当简单。

我们可以设两指针为i,j,指向的水槽板高度分别为 h[i] 和 h[j] ,此状态下水槽板的面积为S(i,j) 。由于可以容纳水的高度有两木板中的短板决定,因此我们有以下面积公式:
s( i , j ) = min( h[i] , h[j] ) x ( j - i )
在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽底边宽度-1变短:

  • 若向内移动短板,水槽的短板min(h[i],h[j])可能变大,因此下个水槽的面积可能增大。
  • 若向内移动长板,水槽的短板mi(h[i],h[j])不变或变小,因此下个水槽的面积一定变小。

所以,只要初始化双指针分列水槽的两端,循环每轮将短板向内移动一格,并每次更新最大面积,直到两指针相遇,代码实现如下:

  1. 普通版本
 public int maxArea(int[] height) {
    int left = 0, right = height.length - 1; // 初始化左右指针,分别指向数组的开头和结尾
    int s = 0; // 用于存储当前计算的容器面积
    int max = 1; // 用于存储最大容器面积的初始值
    // 使用双指针法,从两侧向中间靠拢寻找最大容器面积
    while (left < right) {
        // 计算当前左右指针所围成的容器面积,取较小的高度乘以宽度
        s = Math.min(height[left], height[right]) * (right - left);    
        // 更新最大容器面积
        max = Math.max(max, s);
        // 移动指针的规则是向内移动较小高度的指针,以期望找到更高的边界
        if (height[left] > height[right]) {
            right--; // 右侧高度较小,向内移动右指针
        } else {
            left++; // 左侧高度较小或相等,向内移动左指针
        }
    }    
    return max; 
}

  1. 简约版本
  public int maxArea(int[] height) {
    int i = 0, j = height.length - 1; // 初始化左右指针,分别指向数组的开头和结尾
    int res = 0; // 用于存储当前计算的容器面积的最大值
    // 使用双指针法,从两侧向中间靠拢寻找最大容器面积
    while (i < j) {
        // 计算当前左右指针所围成的容器面积,取较小的高度乘以宽度
        res = height[i] < height[j] ?
            Math.max(res, (j - i) * height[i++]) : // 如果左侧高度较小,向内移动左指针
            Math.max(res, (j - i) * height[j--]); // 如果右侧高度较小,向内移动右指针
    }    
    return res; // 返回最大容器面积
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
滑动窗口算法是一种用于解决一些查找满足一定条件的连续区间的性质的问题的思想或技巧。它可以将双层嵌套的循环问题转换为单层遍历的循环问题,从而降低时间复杂度。滑动窗口算法的步骤通常包括维护两个指针left和right,表示当前窗口的左右边界。通过移动右指针扩大窗口,直到窗口内的元素之和满足某个条件。然后,移动左指针缩小窗口,直到不能再缩小为止。在这个过程中,记录窗口的最小长度,并更新最小长度的值。最后返回最小长度。滑动窗口算法的优点包括时间复杂度较低、空间复杂度较低、简单易懂。然而,滑动窗口算法也有一些缺点,包括无法解决所有子串问题、可能存在重复计算和可能存在局限性。总的来说,滑动窗口算法是一种有效的解决特定类型问题的方法。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [滑动窗口算法精讲(Sliding Window Algorithm)](https://blog.csdn.net/qq_39559641/article/details/122793321)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [滑动窗口算法](https://blog.csdn.net/m0_63951142/article/details/130671127)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值