力扣第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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章