大家好,我是翼同学,这里是【水滴计划 | 刷题日志】
每日两题,拒绝摆烂。
这道题的解题思路在于,最大面积取决于短板。
首先我们定义双指针left
和right
,分别指向水槽的左右两端,如下所示:
int left = 0;
int right = height.size() - 1;
水槽的面积公式为: S = m i n ( h e i g h t [ i ] , h e i g h t [ j ] ) ∗ ( j − i ) S = min(height[i], height[j]) * (j-i) S=min(height[i],height[j])∗(j−i)
为什么说最大面积取决于短板呢?
我们定义双指针后,定义循环条件为left
但为什么不让长板向内移动呢?这是因为,将长板向内移动,即使遇到更长的板,此时水槽的面积也受限于短板,使得面积不可能变大,只会变小。因此,要使水槽面积有变大的可能,只能让短板往内移动。
因此代码如下:
class Solution {
public:
int maxArea(vector& height) {
// 1. 定义双指针 left 和 right
int left = 0;
int right = height.size() - 1;
// 2. 定义一个变量表示最大面积
int maxArea = 0;
// 3. 循环遍历数组
while(left < right) {
// 3.1 如果左板较小,则将左板向右移动
if(height[left] < height[right]) {
// 更新最大面积的值
maxArea = max(maxArea, (right - left) * height[left]);
left++;
}
// 3.2 否则将右板向左移动
else {
// 更新最大面积的值
maxArea = max(maxArea, (right - left) * height[right]);
right--;
}
}
// 4. 返回结果
return maxArea;
}
};
首先,先暴力解法来一遍。(两层for循环)
代码如下:
class Solution {
public:
int removeElement(vector& nums, int val) {
// 1. 拿到数组nums的大小 size
int size = nums.size();
// 2. 第一层循环遍历数组的每个元素
for (int i = 0; i < size; i++) {
// 2.1 如果发现了 移除元素 则将后面的值往前移一位
if (nums[i] == val) {
// 2.2 第二层循环更新数组
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
// 2.3 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
i--;
// 2.4 数组长度减一
size--;
}
}
// 3. 返回结果
return size;
}
};
另一种思路是双指针解法,具体如下所示:
class Solution {
public:
int removeElement(vector& nums, int val) {
// 1. 定义指针left,寻找新数组的元素(新数组指的是不含 val 的数组)
int left = 0;
// 2. 另一个指针right用于遍历数组,指向更新 新数组 的下标位置
for (int right = 0; right < nums.size(); right++) {
// 3. 如果元素不等于val,则原地赋值给新数组
if (nums[right] != val) {
nums[left] = nums[right];
left++;
}
//4. 当然如果等于val,则不管它,因为后面元素会覆盖掉它
}
// 5. 返回新数组的长度
return left;
}
};
好了,今天就刷到这里,明天再来。