「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
一、盛最多水的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
1、说明
说明:你不能倾斜容器。
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
2、实现
核心思路:定义两个指针 L 和 R,分别指向数组的最左边、最右边,依次比较两个数,谁小结算谁,谁小移动谁(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、总结
- 谁小结算谁
- 谁小移动谁
- 只关注会不会推高答案的可能性!
二、步骤和问题
定义何为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、总结
- 拆解题意
- 单调性