简介:本文深入解析LeetCode第11题"盛水最多的容器"的双指针解法,从问题本质、算法逻辑到代码实现,帮助读者掌握双指针技巧在优化问题中的应用。
LeetCode第11题”盛水最多的容器”(Container With Most Water)是算法题库中经典的优化问题。题目给定一个包含n个非负整数的数组,每个整数代表一个垂直线的高度,要求选择两条线与x轴构成一个容器,计算该容器能容纳的最大水量。水量由两条线之间的距离(宽度)和较短线的高度(高度)决定,即面积=宽度×min(高度1,高度2)。
双指针之所以适用于此问题,在于其能有效处理”局部最优”与”全局最优”的关系。传统暴力解法需要遍历所有可能的线对组合,时间复杂度为O(n²),而双指针通过从数组两端向中间移动,每次移动较短线对应的指针,能在O(n)时间内找到最优解。这种策略的核心在于:移动较长线不会增加面积(因为宽度减小且高度受限于较短线),而移动较短线可能找到更高的线从而增加面积。
设置两个指针,left指向数组起始位置(索引0),right指向数组末尾位置(索引n-1)。此时宽度最大(n-1),高度由min(height[left], height[right])决定。
计算当前指针位置的面积:area = (right - left) * min(height[left], height[right])。将此面积与全局最大面积max_area比较,若更大则更新max_area。
比较height[left]和height[right]的大小:
当left指针与right指针相遇时(left >= right),遍历结束,此时max_area即为全局最大面积。
def maxArea(height):left, right = 0, len(height) - 1max_area = 0while left < right:width = right - leftcurrent_height = min(height[left], height[right])current_area = width * current_heightmax_area = max(max_area, current_area)if height[left] < height[right]:left += 1else:right -= 1return max_area
双指针技巧不仅适用于盛水容器问题,还可推广到类似优化问题中,如:
错误逻辑:若height[left] < height[right],移动right指针。这将导致错过可能更高的线,因为移动right指针后,宽度减小且高度仍受限于原left线的高度。
错误逻辑:循环条件为left <= right。当left=right时,宽度为0,面积必然为0,无需计算。
双指针解法的时间复杂度为O(n),因为每个元素最多被访问一次(left和right指针各遍历数组一次)。
空间复杂度为O(1),仅使用常数个额外变量(left, right, max_area等)。
虽然双指针解法已是最优,但可结合其他技巧(如提前终止)处理特定输入。例如,若数组已排序且高度单调递减,可在移动指针时提前判断是否可能找到更大面积。
LeetCode第11题通过双指针解法展示了如何从暴力解法中提炼出高效算法。其核心在于:
对于开发者而言,掌握双指针技巧不仅能高效解决此类优化问题,还能培养对问题本质的洞察力,为解决更复杂的算法问题奠定基础。