• 【水滴计划】:盛最多水的容器、移除元素


    1、写在前面

    大家好,我是翼同学,这里是【水滴计划 | 刷题日志】

    每日两题,拒绝摆烂。

    2、内容

    2.1、题目一:盛最多水的容器

    链接:11. 盛最多水的容器 - 力扣(LeetCode)

    (1) 描述

    (2) 举例

    (3) 解题

    这道题的解题思路在于,最大面积取决于短板

    首先我们定义双指针leftright,分别指向水槽的左右两端,如下所示:

    int left = 0;
    int right = height.size() - 1;
    
    • 1
    • 2

    水槽的面积公式为: 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])(ji)

    为什么说最大面积取决于短板呢?

    我们定义双指针后,定义循环条件为left,即如果双指针相遇则退出循环。在每次循环中,都会将短板向内移动一格,移动之后虽然底部边长-1,但是高度可能会增大,因此下一个水槽的面积或许会增大。

    但为什么不让长板向内移动呢?这是因为,将长板向内移动,即使遇到更长的板,此时水槽的面积也受限于短板,使得面积不可能变大,只会变小。因此,要使水槽面积有变大的可能,只能让短板往内移动。

    因此代码如下:

    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.2、题目二:移除元素

    链接:27. 移除元素 - 力扣(LeetCode)

    (1) 描述

    (2) 举例

    (3) 解题

    首先,先暴力解法来一遍。(两层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;
    
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    另一种思路是双指针解法,具体如下所示:

    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、写在最后

    好了,今天就刷到这里,明天再来。

  • 相关阅读:
    【Django学习笔记(三)】BootStrap介绍
    公司放出消息准备裁员,我被迫学了自动化测试···
    基于Ubuntu20.04运行OP-TEE_3.17.0_QEMU_V8的环境搭建
    集成学习、装袋法、提升法、GBDT、随机森林(机器学习)
    AOP的应用(日志打印)
    考研复习408计算机网络——物理层
    PHP代码审计入门-DVWA靶场CSRF篇
    【数学建模】基于SIR模型实现新冠病毒COVID-19估计附matlab代码
    计算机网络 - 传输层 选择填空复习题
    PTA 7-87 A±B
  • 原文地址:https://blog.csdn.net/m0_62999278/article/details/127812091