欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

算法-盛最多水的容器(双指针法)

程序员文章站 2024-03-25 20:31:04
...

力扣(LeetCode)连接 盛最多水的容器

题目:
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

算法-盛最多水的容器(双指针法)
解体思路:
双指针从两边向中间运算,比较左右两个容器壁大小,让一方小的主动向另外一方靠近(因容器盛水量大小受小的一方影响,如果挪动大的,加上两壁距离-1,这样只会让盛水量更小),直到两者相等(循环条件);

示例:

输入:[1,8,6,2,5,4,8,3,7]
输出:49

下面是自己实现的几种方式比较,还请大佬勿喷;有更好的思路还请指点评论留言

实现方式一:(暴力解题法,缺点时间复杂度n^2,效率较低)

	public static int maxArea(int[] height) {
		int maxArea = 0;
		for (int i = 0; i < height.length; i++) {
			for (int j = i + 1; j < height.length; j++) {
				int area = (j - i) * (height[i] > height[j] ? height[j] : height[i]);
				maxArea = area > maxArea ? area : maxArea;
			}
		}
		return maxArea;
	}

实现方式二:(双指针法减少时间复杂度,存在的其他问题:既有循环又有判断,用while更高效一些,减少了像i这种非必要的变量,并且无需再判断退出条件;并且循环次数不够准确,效率不高)

	public static int maxArea1(int[] height) {
		int maxArea = 0;
		int p = 0;
		int q = height.length - 1;
		for (int i = 0; i < height.length; i++) {
			maxArea = Math.max((q - p) * Math.min(height[p], height[q]), maxArea);
			if (q > p) {
				if (height[p] > height[q]) {
					q--;
				} else {
					p++;
				}
			}
		}
		return maxArea;
	}

实现方式三: (替换成while结果,减少了不必要的循环次数;)

	public static int maxArea2(int[] height) {
		int maxArea = 0;
		int p = 0;
		int q = height.length - 1;
		while (p < q) {
			if (height[p] > height[q]) {
				maxArea = Math.max((q - p) * height[q], maxArea);
				q--;
			} else {
				maxArea = Math.max((q - p) * height[p], maxArea);
				p++;
			}
		}
		return maxArea;
	}