力扣第29场双周赛 5434. 删掉一个元素以后全为 1 的最长子数组

  1. 删掉一个元素以后全为 1 的最长子数组 显示英文描述
    通过的用户数 1225
    尝试过的用户数 1340
    用户总通过次数 1257
    用户总提交次数 2472
    题目难度 Medium
    给你一个二进制数组 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 。

思路一

首先统计一下0,1的个数,然后看连续0的个数,如果连续0的个数为1,可以
考虑将前后连续的1加起来,如果和大于当前计算的最大值,则更新最大值,如果连续的0个数大于1,则不考虑前后相加,因为最多只能删除一个数据。
考虑边界条件,如果全部为0,则返回0
如果全部为1,则返回数据长度-1,
其余是既包含0也包含1:
当前是连续的1,比较一下最大值,如果大于最大值则更新。
class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        
        map<int,map<int,int>> mapOneZeroNum;
        map<int,int> mapTemp;
        int index = 0;
        for(int i = 0; i < nums.size(); i++)
        {//统计连续0,1的个数
            if(i > 0 && nums[i]!=nums[i-1]) 
            {//数据变化前更新下标
                index++;
                mapTemp.clear();
            }
            if(0 == nums[i])
            {
                mapTemp[0]++;
                mapOneZeroNum[index] = mapTemp;
            }
            else 
            {
                mapTemp[1]++;
                mapOneZeroNum[index] = mapTemp;
            }
        }
        
        int maxLen = 0;
        int len = mapOneZeroNum.size();
        if(len == 0)
        {
            return 0;
        }
        else if(len == 1)
        {//长度为1的情况
            if(mapOneZeroNum[0].begin()->first == 1)
                return mapOneZeroNum[0][1] - 1;
            if(mapOneZeroNum[0].begin()->first == 0)
                return 0;
        }
        else
        {
      
        	for(int i = 0; i < len; i++)  
        	{//连续0个数为1的情况
           		 if(i > 0 && i < (len - 1) && mapOneZeroNum[i].begin()->first == 0 && mapOneZeroNum[i].begin()->second == 1)
            	{
                	int tempLen = mapOneZeroNum[i-1].begin()->second + mapOneZeroNum[i+1].begin()->second;
                	if(tempLen > maxLen)
                    	maxLen = tempLen;
            	}
             //更新当前连续为1的长度
           	 if(mapOneZeroNum[i].begin()->first == 1)
             {
               	 int tempLen = mapOneZeroNum[i].begin()->second;
                 if(tempLen > maxLen)
                    maxLen = tempLen;
             }
            
           }
        }
        return maxLen;
        
    }
};

思路二 时间复杂度O(n)

统计0左右两侧1的数量,遇到0就将右侧数据赋值给左侧
class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        
        int max = 0,left = 0,right = 0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]==0)
            {
                left = right;
                right = 0;
            }
            else if(nums[i]==1)
            {
                right++;
            }
            if(right + left > max)
                max = right + left;
        }
        
        return max==nums.size()?max-1:max;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章