一、题目
二、思路
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 举一反三
不能局限于模板,要有好的设计思路,当然这也不是一时半会儿能学会的