盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:(如上图)
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1]
输出:1
我的思路
这道题和算法十二那道柱状图中最大矩形一题类似,还是双重循环
网上思路
双指针
我的思路
var maxArea = function (height) {
let len = height.length
let max = 0
for (let i = 0; i < len; i++) {
for (let j = 0; j < len; j++) {
let width = j - i
let minHeight = height[j] <= height[i] ? height[j] : height[i]
max = Math.max(max, width * minHeight )
}
}
return max
};
讲解
具体讲解可见算法十二
网上思路
var maxArea = function (height) {
let left = 0;
let right = height.length - 1;
let maxWater = 0;
while (left < right) {
const currentHeight = Math.min(height[left], height[right]);
const currentWidth = right - left;
const currentWater = currentHeight * currentWidth;
maxWater = Math.max(maxWater, currentWater);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxWater;
};
讲解
- 定义参数
left: 初始化为 0,表示从数组的左端开始。
right: 初始化为 height.length - 1,表示从数组的右端开始。
maxWater: 用于存储当前找到的最大水容量,初始化为 0。- while (left < right) {
这个 while 循环 会在 left 小于 right 时继续执行,确保只在两个指针之间进行比较。- const currentHeight = Math.min(height[left], height[right])
const currentWidth = right - left
const currentWater = currentHeight * currentWidth;
currentHeight: 计算当前两条线段的较小高度,因为水的容量取决于较短的那一边。
currentWidth: 计算当前容器的宽度,即两个指针之间的距离。
currentWater: 计算当前容器的水容量,公式为 高度 * 宽度。- if (height[left] < height[right]) {
left++;
} else {
right–;
}
根据当前两条线段的高度,决定移动哪个指针:
如果左边的高度小于右边的高度,移动左指针向右**(left++),以寻找可能更高的线段。
否则,移动右指针向左(right–)**,同样寻找可能更高的线段。
两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你不可以重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
我的思路
之前做过这种题,循环和Map(),今天就试一下双指针看看
网上思路
也是双指针
我的思路
var twoSum = function (numbers, target) {
let left = 0;
let right = numbers.length - 1;
while (left < right) {
let currentSum = numbers[left] + numbers[right];
if (currentSum === target) {
return [left + 1, right + 1];
} else if (currentSum < target) {
left++;
} else {
right--;
}
}
};
讲解
经过这两天的练习,对双指针的了解更多了一点,所以这里就是用它来解题。
- 定义双指针变量,一个从 0 开始,一个从最后一位开始
- 双指针的循环条件一般都是 left < right
- 题目要求求和,所以 while循环 内部的判断条件应该和传来的 target 有关
- 因为是双指针,所以也要根据求和值来判断什么时候移动指针
总结
- 盛最多水的容器这题,我本来想用栈解决的,但是在写代码的时候,发现及时我用了算法十二的栈写法,出来的答案也不对,最后还是选择了双重循环,回头我看一下到底是什么原因导致的
- 双指针还是比较好理解的