Bootstrap

1493. 删掉一个元素以后全为 1 的最长子数组

一、题目

在这里插入图片描述

二、思路

2.1 解题思路

2.2 代码尝试

class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int len=0;
        int l=0;
        int a=1;
        int ret=1;
        int pos=0;
        //用乘积来作为窗口的满足条件,如果小于1,说明窗口内包含了0
        for(int r=0;r<nums.size();r++){
            
            ret*=nums[r];
            while(ret<1){
                if(a>0){
                    ret=1;
                    a--;
                }else{
                    len=max(len,r-l);
                    l=pos+1;
                }
                pos=r;
            }
            len=max(len,r-l+1);
        }
        return len;
    }
};

2.3 疑难问题

2.4 复盘

乘积溢出问题:使用乘积来判断子数组是否满足条件可能会导致整数溢出问题,尤其是当数组中的元素较大时。可以考虑使用对数或其他方法来避免溢出。
逻辑错误:代码中的 a 变量用于记录是否已经删除了一个0,但逻辑上不够清晰。当 ret < 1 时,代码会尝试删除一个0,但删除0后并没有正确地更新窗口的左边界 l。

三、解法

class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int ans = 0;
        int p0 = 0, p1 = 0;
        for (int num: nums) {
            if (num == 0) {
                p1 = p0;
                p0 = 0;
            }
            else {
                ++p0;
                ++p1;
            }
            ans = max(ans, p1);
        }
        if (ans == nums.size()) {
            --ans;
        }
        return ans;
    }
};


四、收获

4.1 心得

这个解法真是妙啊,并没有用一个全局变量来标记是否用过0,另外一种思路,就是用指针更新,p1指针有了两次机会,妙。所以说好的代码是从设计、思路上就很优越。

4.2 举一反三

不能局限于模板,要有好的设计思路,当然这也不是一时半会儿能学会的
;