盛最多水的容器&步骤和问题

121 阅读2分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

一、盛最多水的容器

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

LeetCode

1、说明

说明:你不能倾斜容器。

img

输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

2、实现

核心思路:定义两个指针 LR,分别指向数组的最左边最右边,依次比较两个数,谁小结算谁谁小移动谁(L向右移动 或 R向左移动),每次滑动的过程产生一个结果,最后在所有结果中找最大值就是盛水最多的容器答案。

3、代码

    // 时间复杂度O(n)
    public static int maxArea(int[] h) {
        int max = 0;
        int l = 0;
        int r = h.length - 1;
        while (l < r) {
            max = Math.max(max, Math.min(h[l], h[r]) * (r - l));
            if (h[l] > h[r]) {
                r--;
            } else {
                l++;
            }
        }
        return max;
    }

4、总结

  1. 谁小结算谁
  2. 谁小移动谁
  3. 只关注会不会推高答案的可能性!

二、步骤和问题

定义何为step sum? 比如680,680 + 68 + 6 = 754,680的step sum叫754 给定一个正数num,判断它是不是某个数的step sum

1、分析

拆解题意:比如给定一个正数num = 754,它是680的step sum

所以给定任意一个正数num,那么可以从1~num之间利用二分查找法来,比较中间数的步长数num是否相等。

2、实现

	public static boolean isStepSum(int stepSum) {
		int L = 0;
		int R = stepSum;
		int M = 0;
		int cur = 0;
		while (L <= R) {
			M = L + ((R - L) >> 1);
			cur = stepSum(M);
			if (cur == stepSum) {
				return true;
			} else if (cur < stepSum) {
				L = M + 1;
			} else {
				R = M - 1;
			}
		}
		return false;
	}

	public static int stepSum(int num) {
		int sum = 0;
		while (num != 0) {
			sum += num;
			num /= 10;
		}
		return sum;
	}

3、总结

  1. 拆解题意
  2. 单调性