给你一个二进制数组 nums ,你需要从中删掉一个元素。

请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。

如果不存在这样的子数组,请返回 0 。

 

提示 1:

输入:nums = [1,1,0,1]
输出:3
解释:删掉位置 2 的数后,[1,1,1] 包含 3 个 1 。
示例 2:

输入:nums = [0,1,1,1,0,1,1,0,1]
输出:5
解释:删掉位置 4 的数字后,[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1] 。
示例 3:

输入:nums = [1,1,1]
输出:2
解释:你必须要删除一个元素。
示例 4:

输入:nums = [1,1,0,0,1,1,1,0,1]
输出:4
示例 5:

输入:nums = [0,0,0]
输出:0
 

提示:

1 <= nums.length <= 10^5
nums[i] 要么是 0 要么是 1 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-subarray-of-1s-after-deleting-one-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

做题思路:

1、首先对原数组nums进行处理,在首尾各添加一个元素0,生成新的数组a,便于下一步计算。

2、然后对数组a中的元素进行对比。比较里边是否有0元素,并记录0元素的下标在zero数组中。

3、之后,对zero数组中的元素两两相减,从而得到0元素下表的差值,代表0元素之间存在的1的个数,记录在b数组中。

4、再之后,对b数组中元素进行两两求和,并进行降序排列,得到其最大值。对其进行输出。

int compDec(const void *a, const void *b)
{
    return *(int *)b - *(int *)a;
}
int longestSubarray(int* nums, int numsSize){
    int i,k=0,m;
    int zero[numsSize+2];
    int a[numsSize+2];
    a[0]=0;
    a[numsSize+1]=0;
    for(i=0;i<numsSize;i++)
    {
        a[i+1]=nums[i];                              //对num数组首尾加上0元素,重新复制给a获得新的数组
    }
    for(i=0;i<numsSize+2;i++)
    {
        if(a[i]==0)
        {
            zero[k++]=i;                             //记录0元素的下标
        }
    }
    int b[numsSize+2];
    for(i=0;i<k-1;i++)
    {
        b[i]=zero[i+1]-zero[i];                 //计算0元素下标之间的差值,即求存在的1的个数(0元素下标相减,得到的结果比1的长度要大1)
    }
     int c[numsSize+2];
     for(i=0;i<k-2;i++)
     {
         c[i]=b[i+1]+b[i];                        //计算去掉元素0之后1最长的情况
     }
    qsort(c, k-2, sizeof(b[0]), compDec);
    m=c[0]-2;                          
//对于数组中不存在0元素的数组进行判断
    if(k==2)                               
    {
        m=numsSize-1;
    }
 
 
    return m;
}