Given a binary array nums, you should delete one element from it.
Return the size of the longest non-empty subarray containing only 1's in the resulting array.
Return 0 if there is no such subarray.
 
Example 1:
Input: nums = [1,1,0,1]
Output: 3
Explanation: After deleting the number in position 2, [1,1,1] contains 3 numbers with value of 1's.
Example 2:
Input: nums = [0,1,1,1,0,1,1,0,1]
Output: 5
Explanation: After deleting the number in position 4, [0,1,1,1,1,1,0,1] longest subarray with value of 1's is [1,1,1,1,1].
Example 3:
Input: nums = [1,1,1]
Output: 2
Explanation: You must delete one element.
Example 4:
Input: nums = [1,1,0,0,1,1,1,0,1]
Output: 4

Example 5:
Input: nums = [0,0,0]
Output: 0

 
Constraints:

1 <= nums.length <= 10^5
nums[i] is either 0 or 1.

Difficulty: interview

Starter code:

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        

Solutions:
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if not 0 in nums:
            return len(nums) - 1
        ans = 0
        tot = 0
        prev = 0
        
        for n in nums:
            if n == 1:
                tot += 1
            else:
                ans = max(tot+prev, ans)
                prev = tot
                tot = 0
        return max(prev+tot, ans)
                


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        z=[0]
        l=[]
        a=0
        c=0
        for i in range(len(nums)):
            if a==1 and nums[i]==0:
                z.append(c)
                c=(i)-(l[-1]+1)
                a=1
                l.append(i)
            elif nums[i]==0:
                a=a+1
                l.append(i)
            elif nums[i]==1:
                c=c+1
        z.append(c)
        if nums.count(1)==len(nums):
            return len(nums)-1
        return max(z)
                


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        #Full of one's or Zero
        zc,oc=0,0
        for i,v in enumerate(nums):
            if v:oc+=1
            else:zc+=1
        if oc==len(nums):return oc-1
        elif zc==len(nums):return 0
        elif zc==1: return oc
        elif oc==1: return 1
        else:
            #calculate left one's once to make your algo look better
            l=r=0
            for i,v in enumerate(nums):
                if v==1:
                    l+=1
                else:
                    break
            st=i+1
            #print(i,nums[i])
            po=i
            maxo,maxi=-1,-1
            while(st < len(nums)):
                if nums[st]==1:
                    r+=1
                    st+=1
                    continue
                else:
                    v=l+r
                    if maxo < v:
                        maxo=v
                        maxi=po
                    po=st
                    l=r
                    r=0
                    st+=1
            maxo=max(maxo,l+r)
            return maxo
                    
                    
                
                    


from collections import deque
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n=len(nums)
        if n==0:
            return 0
        elif n==1:
            return 0 if nums[0]==0 else 1
        q=deque()
        num_z=0
        maxx=0
        is_0 = 0
        for i in range(n):
            if nums[i]==1:
                q.append(i)
                continue
            is_0=1
            if num_z<1:
                q.append(i)
                num_z+=1
                maxx = max(maxx, len(q)-1)
                continue
            maxx=max(maxx, len(q)-1)
            while q and num_z==1:
                top = q.popleft()
                if nums[top]==0:
                    num_z-=1
            q.append(i)
            num_z+=1
        
        if is_0==0:
            return n-1
        maxx = max(len(q)-num_z, maxx)
        
        return maxx


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        c=0
        ind=0
        for i in range(len(nums)):
            if nums[i]==0:
                j=i+1
                k=0
                while j<len(nums) and nums[j]==1:
                    k+=1
                    j+=1
                j=i-1
                while j>=0 and nums[j]==1:
                    k+=1
                    j-=1
                if k>c:
                    c=k
                    ind=i
        if ind==0 and nums[ind]==1:
            ind=len(nums)-1
            c=len(nums)-1
        return c


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        res=zeros=0
        zero_i=None
        i=0
        for j,v in enumerate(nums):
            if v==0:
                zeros+=1
                if zeros==2:
                    i=zero_i+1
                    zeros=1
                zero_i=j
            res=max(res,j-i)
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        max_length = 0
        count = 0
        for num in nums:
            if num == 1:
                count += 1
                max_length = max(max_length, count)
            else:
                count = 0
        
        if max_length == len(nums):
            return len(nums) - 1
        elif max_length == 0:
            return 0
        
        num_left = 0
        num_right = 0
        for i, num in enumerate(nums):
            if num == 1:
                num_right += 1
            else:
                max_length = max(max_length, num_left + num_right)
                if i + 1 < len(nums) and nums[i + 1] == 1:
                    num_left = num_right
                    num_right = 0
                else:
                    num_left = 0
                    num_right = 0
        max_length = max(max_length, num_left + num_right)
        
        return max_length

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        start,end,maxlen,k = 0,0,0,1
        
        while(end<len(nums)):
            if nums[end]==0:
                k=k-1
                
            if k<0:
                if nums[start]==0:
                    k+=1   
                start = start+1
                end = end+1
                continue
                
            if k>=0 or nums[end]==1:
                maxlen = max(maxlen,end-start)
                end = end + 1
            
        return maxlen
                
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        longest = 0
        
        left = 0
        x = 1
        
        for right in range(len(nums)):
            if not nums[right]:
                x -= 1
            
            while x < 0:
                if not nums[left]:
                    x += 1
                
                left += 1
            
            longest = max(longest, right - left + 1)
        
        return longest - 1


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        
        noofones = 0
        m = 0
        lastoneslen = 0
        
        for i in nums:
            if i == 1:
                noofones += 1
            else:
                m = max(m, noofones+lastoneslen)
                lastoneslen = noofones
                noofones = 0
        
        m = max(m, noofones+lastoneslen)
        
        if m == len(nums):
            m -= 1
        
        return m
        
        
#         max_ones_len = 0
#         num_of_ones = 0
#         last_ones_len = 0
        
#         for num in nums:
#             if num == 1:
#                 num_of_ones +=1
#             else:
#                 max_ones_len = max(max_ones_len, last_ones_len + num_of_ones)
#                 last_ones_len = num_of_ones
#                 num_of_ones = 0
        
#         max_ones_len = max(max_ones_len, last_ones_len + num_of_ones)
        
#         if max_ones_len == len(nums):
#             max_ones_len -= 1
            
#         return max_ones_len


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        max_count = 0
        start = 0
        zero = 2
        
        for i in range(len(nums)):
            if nums[i] == 0:
                zero -= 1
            while zero < 1:
                if nums[start] == 0:
                    zero += 1
                start += 1
            max_count = max(max_count, i - start)
        
        return max_count
                    


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        res = []
        count = 0
        for i, val in enumerate(nums):
            if val == 0:
                if count > 0:
                    res.append(count)
                    count = 0
                res.append(0)
            elif val == 1:
                count += 1
        if count > 0:
            res.append(count)
        lenRes = len(res)
        ma = 0
        if lenRes > 2:
            for i in range(1, lenRes-1):
                ma = max(max(ma, res[i-1] + res[i+1]), max(res[i-1], res[i]), max(res[i+1], res[i]))
            return ma
        
        else:
            if lenRes == 1 and res[0] > 0:
                return res[0] - 1
            elif lenRes == 1 and res[0] == 0:
                return ma
            elif lenRes == 2:
                return max(res[0], res[1])
            
                
            
        
        
        
        
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        zero = -1
        k = 1
        maxi = 0
        count = 0
        i = 0
        while i != len(nums):
            if nums[i] == 0:
                if k == 0:
                    i = zero + 1
                    zero = i
                    maxi = max(count, maxi)
                    count = 0
                    k = 1
                else:
                    k -= 1
                    zero = i
                    i += 1                    
            else:
                count += 1
                i += 1
        maxi = max(count, maxi)
        if maxi == len(nums):
            return maxi - 1
        else:
            return maxi

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        start = end = zeros = ones = maxx = 0
        while end < len(nums):
            if nums[end] == 1:
                ones += 1
            elif nums[end] == 0:
                zeros += 1
                
            while zeros > 1:
                if nums[start] == 0:
                    zeros -= 1
                start += 1
            maxx = max(maxx,end - start)
            end += 1
        return maxx

class Solution:
    def longestSubarray(self, array: List[int]) -> int:
        i=0
        lenght=0
        stack=deque()
        zero=False
        while i <len(array):
            if array[i]==1:
                stack.append(array[i])
                i+=1
            else:
                if zero==False:
                    stack.append(array[i])
                    zero=True
                    i+=1
                else:
                    temp=len(stack)-1
                    if temp>lenght:
                        lenght=temp
                    while stack[0]!=0:
                        stack.popleft()
                    stack.popleft()
                    zero=False
            if len(stack)>lenght:
                lenght=len(stack)-1
        return (lenght)



class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        left = 0
        right = 0
        
        zeroes = 1
        res = 0
        while right < len(nums):
            if nums[right] == 0:
                zeroes -= 1
            
            
            while zeroes < 0:
                if nums[left] == 0:
                    zeroes += 1
                left += 1
            
            res = max(res, right - left)
            right += 1
            
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        i, j = 0, 0
        ans, cur = 0, 0
        while j < len(nums):
            cur += nums[j]
            while i < j and cur < j-i:
                cur -= nums[i]
                i += 1
            ans = max(ans, cur)            
            j += 1
        return min(ans, len(nums)-1)
                
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return 0
        joined = [0 for i in range(n)]
        # downto = [0 for i in range(n)]
        left = 0
        right = 0
        for i in range(n):
            joined[i] += left
            joined[n - 1 - i] += right
            if nums[i] == 1:
                left += 1
            else:
                left = 0
            if nums[n - 1 - i] == 1:
                right += 1
            else:
                right = 0
        
        return max(joined)

class Solution:
    def longestSubarray(self, nums):
        n = len(nums)
        last_zero = None
        last_one = None
        cnt = 0
        res = 0
        for i in range(n):
            if nums[i] == 1:
                if last_one is None:
                    last_one = i
                cnt += 1 
            else:
                if last_zero is None:
                    last_zero = i
                else:
                    last_one = last_zero + 1
                    last_zero = i
                    cnt = i - last_one
            res = max(res, cnt)
        if res == n:
            return n - 1
        return res    

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        mc = 0
        onep = False
        for i in range(len(nums)):
            if nums[i] == 0:
                c = 0
                j = i - 1
                while j >=0 and nums[j] !=0:
                    j -= 1
                    c+=1 
                    
                j = i + 1
                while j<len(nums) and nums[j] != 0:
                    j += 1
                    c += 1
                    
                if c > mc:
                    mc = c 
            else:
                onep = True
                    
        if onep and mc == 0:
            return len(nums) - 1
        
        elif not onep and mc == 0:
            return 0
        else:
            return mc
        
                    
                    


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        groups = [[k, len(list(g))] for k, g in itertools.groupby(nums)]
        if len(groups) == 1:
            return groups[0][1] - 1 if groups[0][0] else 0
        ans = 0
        for i in range(len(groups)):
            k, klen = groups[i]
            if k:
                ans = max(ans, klen)
            elif i not in [0, len(groups)-1] and klen == 1:
                ans = max(ans, groups[i-1][1] + groups[i+1][1])
        return ans

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        low, high = 0, 0
        cn = 0
        ans = 0
        
        while low < len(nums) and high < len(nums):
            if nums[high] == 0:
                if cn < 1:
                    cn += 1
                else:
                    while nums[low] != 0:
                        low += 1
                    low += 1
            high += 1
            ans = max(ans, high - low)
            
        
        return max(ans, high-low)-1

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        res=zeros=0
        zero_i=None
        i=0
        for j,v in enumerate(nums):
            if v==0:
                zeros+=1
                if zeros>1:
                    i=zero_i+1
                    zeros-=1
                zero_i=j
            res=max(res,j-i)
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        res=zeros=zero_i=i=0
        for j,v in enumerate(nums):
            if v==0:
                zeros+=1
                if zeros==2:
                    i=zero_i+1
                    zeros=1
                zero_i=j
            res=max(res,j-i)
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        # dynamic programming, store largest subarray including element i with/without deleting
        # let dp[i][0] be the longest subarray of all 1s including i
        # let dp[i][1] be the longest subarray of all 1s with 1 zero including i
        
        if not nums: return 0
        if all(nums): return len(nums)-1 # must delete 1 element
        
        n = len(nums)
        dp = [[0]*2 for _ in range(n)]
        dp[0][0] = 1 if nums[0] == 1 else 0
        dp[0][1] = 0
        
        res = 0
        for i in range(1, n):
            if nums[i] == 1:
                dp[i][0] = dp[i-1][0] + 1 # dp[i][0] is all 1s, so if nums[i] is a num then increment current all 1s
                dp[i][1] = dp[i-1][1] + 1 # if we have a 1, then increment 1 deletion by 1
            else:
                dp[i][0] = 0 # not allowed to have a zero for dp[i][0]
                dp[i][1] = dp[i-1][0] # if we have a zero, then we are allowed 1 deletion, so ignote current element and hold subarray of all 1s from previous
            
            res = max(res, dp[i][1], dp[i][0]) # check if max is with the i'th element
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        start = end = zeros = ones = maxx = 0
        while end < len(nums):
            if nums[end] == 0:
                zeros += 1
            else:
                ones += 1
                
            while zeros > 1:
                if nums[start] == 0:
                    zeros -= 1
                start += 1
            maxx = max(maxx,end - start)
            end += 1
        return maxx

class Solution:
    def longestSubarray(self, A):
        if not A:
            return 0
        n = len(A)
        right = 0
        cnt = 0
        res = 0
        for left in range(n):
            while right <= n - 1 and (cnt == 0 or A[right] == 1):
                cnt += (A[right] == 0)
                right += 1
            res = max(res, right - left)
            cnt -= (A[left] == 0)
        return res - 1

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        left = []
        total = 0
        for n in nums:
            if n == 0:
                total = 0
            else:
                total += n
            left.append(total)
        
        right = []
        total = 0
        for i in range(len(nums)-1, -1, -1):
            if nums[i] == 0:
                total = 0
            else:
                total += nums[i]
            right.append(total)
        right = right[::-1]
        
        curMax = 0
        for i in range(len(nums) - 2):
            curMax = max(left[i]+right[i+2], curMax)
            
        return curMax

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        l, r = [0] * n, [0] * n
        for i in range(1, n):
            l[i] = l[i-1] + 1 if nums[i-1] == 1 else 0
        for i in range(n-2, -1, -1):
            r[i] = r[i+1] + 1 if nums[i+1] == 1 else 0
        ans = max(r[0], l[n-1])
        for i in range(1, n-1):
            ans = max(ans, l[i] + r[i])
        return ans

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        k = 1
        i = 0
        for j in range(len(nums)):
            if nums[j] == 0: k -= 1
            if k < 0:
                if nums[i] == 0: k += 1
                i += 1
        return j-i

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return 0
        joined = [0 for i in range(n)]
        # downto = [0 for i in range(n)]
        left = 0
        right = 0
        result = 0
        for i in range(n):
            joined[i] += left
            joined[n - 1 - i] += right
            result = max(result, joined[i], joined[n - 1 - i] )
            if nums[i] == 1:
                left += 1
            else:
                left = 0
            if nums[n - 1 - i] == 1:
                right += 1
            else:
                right = 0
        
        return result

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        prevStart = -1
        candidates = []
        if 0 not in nums:
            return len(nums) - 1
        for i in range(len(nums)):
            if nums[i] == 1:
                if prevStart == -1:
                    prevStart = i
                    continue
            else:
                if prevStart != -1:
                    candidates.append([prevStart, i - 1])
                    prevStart = -1
        if prevStart != -1:
            candidates.append([prevStart, len(nums) - 1])
        
        res = [0]
        for i in range(len(candidates)):
            if i == len(candidates) - 1:
                res.append(candidates[i][1] - candidates[i][0] + 1)
            else:
                if candidates[i + 1][0] - candidates[i][1] == 2:
                    res.append(candidates[i + 1][1] - candidates[i][0])
                else:
                    res.append(candidates[i][1] - candidates[i][0] + 1)
        return max(res)

'''
Using sliding window

Method 1:
Sliding window size shrinks

Use i and j as the lower and upper bounds, both inclusively;
Loop through the nums by upper bound, accumulate current element on the sum, then check if sum is less than j - i (which implies the window includes at least 2 0s) : if yes, keep increase the lower bound i till either the sliding window has at most 1 zero or lower bound is same as upper bound;
Core concept here: - credit to @lionkingeatapple and @abhinav_7.
sum count the number of 1s in the window.
j - i means the length of the window - 1. Since we need to delete one element which is zero from this window, we use j - i not j - i + 1.
Specifically, if

sum == (j - i) + 1
then all 1's exist in the window(i - j); if

sum == (j - i)
one zero exist; if

sum < (j - i)
more than one zeros exist!

TC: O(n)
SC: O(1)
'''
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        i = 0
        j = 0
        sum = 0
        ans = 0
        
        for j, val in enumerate(nums):
            sum += val
            while(i < j and sum < j-i):
                sum -= nums[i]
                i+=1
                
            ans = max(ans, j-i)    
        
        return ans


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        leftones = [0] * n
        for i in range(n):
            if nums[i] == 0: leftones[i] = 0
            else: leftones[i] = 1 if i == 0 else leftones[i-1]+1
                
        rightones = [0] * n
        for i in range(n-1, -1, -1):
            if nums[i] == 0: rightones[i] = 0
            else: rightones[i] = 1 if i == n-1 else rightones[i+1]+1
                
        res = 0
        for i in range(1, n-1):
            res = max(res, leftones[i-1] + rightones[i+1])
        
        return res


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        prev, curr, best = 0, 0, 0
        n = len(nums)
        for i, x in enumerate(nums):
            if x == 0:
                best = max(best, prev+curr)
                
                if i == n-1:
                    pass  
                
                elif nums[i+1] == 1: # this is a gap
                    prev = curr
                    curr = 0
                else:
                    prev = 0
                    curr = 0
            else:
                curr += 1
                
        best = max(best, prev+curr)
        
        if best == n: # all ones, need to remove one element at least
            best -= 1
                
        return best

# 23:30
# 00:43
class Solution:
    def longestSubarray(self, xs: List[int]) -> int:
        # DP: find optimal solution ending at i and then 
        n = len(xs)
        
        if n < 2:
            return 0
        
        dp = collections.deque()
        best = 0
        for i, x in enumerate(xs):
            if x:
                dp.append(i)
            while dp and i - dp[0] - len(dp) + 1 > 1:
                dp.popleft()
            nholes = i - dp[0] - len(dp) + 1 if dp else 1
            this_len = len(dp) - (not dp[0] and not nholes) if dp else 0
            best = max(best, this_len)
                
        return best

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        prev, _next, n = [0 for _ in range(len(nums))], [0 for _ in range(len(nums))], len(nums)
        
        count = 0
        for i in range(n):
            num = nums[i]
            if i == 0:
                if num:
                    count = 1
            else:
                if num:
                    prev[i] = count 
                    count += 1
                else:
                    prev[i] = count
                    count = 0
        
        count = 0
        for i in range(n-1, -1, -1):
            num = nums[i]
            if i == n - 1:
                if num:
                    count = 1
            else:
                if num:
                    _next[i] = count 
                    count += 1
                else:
                    _next[i] = count
                    count = 0
        
        _max = 0
        
        for i in range(n):
            num = nums[i]
            _max = max(_max, prev[i] + _next[i])
        
        return _max

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if all(nums):
            return len(nums)-1
        m = pre = l = pl = 0
        for i, n in enumerate(nums):
            if n == pre == 1:
                l += 1
            elif n == pre == 0:
                pl = 0
            elif n == 1 != pre:
                l = 1
            else:
                m = max(m, pl + l)
                pl = l
            pre = n
        return max(m, pl + l) if pre == 1 else m

# 1493. Longest Subarray of 1's After Deleting One Element

def get_longest (nums):
    arr = [1-x for x in nums]
    l, r = 0, 0
    count = 0
    max_length = 0
    while l < len (arr):
        if r == len (arr): step = 'l'
        elif l == r: step = 'r'
        elif count + arr[r] > 1: step = 'l'
        else: step = 'r'

        if step == 'l':
            count -= arr[l]
            l += 1
        else:
            count += arr[r]
            r += 1
            max_length = max (max_length, r - l)

    return max (0, max_length - 1)


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        return get_longest(nums)

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        new_array = list()
        current_segment = 0
        for num in nums:
            if num == 0:
                if current_segment > 0:
                    new_array.append(current_segment)
                    current_segment = 0
                new_array.append(0)
            else:
                current_segment += 1
        if current_segment > 0:
            new_array.append(current_segment)
            
        max_length = 0
        for idx in range(len(new_array)):
            max_length = max(max_length, new_array[idx])
            if idx > 0 and idx < len(new_array) - 1 and new_array[idx] == 0:
                if new_array[idx - 1] > 0 and new_array[idx + 1] > 0:
                    max_length = max(max_length, new_array[idx - 1] + new_array[idx + 1])
                    
        if max_length == len(nums):
            return max_length - 1
        else:
            return max_length


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        right = [0 for _ in range(len(nums))]
        left = [0 for _ in range(len(nums))]
        
        for i in range(1, len(nums)):
            if nums[i - 1] == 1:
                left[i] = 1 + left[i - 1]
             
        res = float('-inf')
        for i in range(len(nums) - 2, -1, -1):
            if nums[i + 1] == 1:
                right[i] = 1 + right[i + 1]
            res = max(res, left[i] + right[i])
        
        # res = float('-inf')
        # for i in range(len(nums)):
        #     res = max(res, left[i] + right[i])
        return res

class Solution:
    # Time: O(n)
    # Space: O(n)
    def longestSubarray(self, nums: List[int]) -> int:
        right = [0 for _ in range(len(nums))]
        left = [0 for _ in range(len(nums))]
        
        for i in range(1, len(nums)):
            if nums[i - 1]:
                left[i] = 1 + left[i - 1]
             
        for i in range(len(nums) - 2, -1, -1):
            if nums[i + 1]:
                right[i] = 1 + right[i + 1]
            
        res = float('-inf')
        for i in range(len(nums)):
            res = max(res, left[i] + right[i])
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        se=set(nums)
        if(0 not in se):
            return len(nums)-1
        elif(1 not in se):
            return 0
        
        count=0
        flag=0
        ls=[]
        for i in nums:
            if(i==0):
                if(flag==0):
                    count+=1
                else:
                    flag=0
                    ls.append(count)
                    count=1
            else:
                if(flag==1):
                    count+=1
                else:
                    flag=1
                    ls.append(count)
                    count=1
        ls.append(count)
        # print(ls)
        ind=0
        ans=0
        while(ind<len(ls)):
            if(ls[ind]!=0):
                if(ls[ind]==1):
                    if(ind==0 and ind<len(ls)-1):
                        ans=max(ans,ls[ind+1])
                    elif(ind==len(ls)-1 and ind>0):
                        ans=max(ans,ls[ind-1])
                    else:
                        if(ind<len(ls)-1 and ind>0):
                            ans=max(ans,ls[ind-1]+ls[ind+1])
                else:
                    if(ind==0 and ind<len(ls)-1):
                        ans=max(ans,ls[ind+1])
                    elif(ind==len(ls)-1 and ind>0):
                        ans=max(ans,ls[ind-1])
                    else:
                        if(ind<len(ls)-1 and ind>0):
                            ans=max(ans,max(ls[ind-1],ls[ind+1]))
            # print(ans,ind)
            ind+=2
            
        return ans

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        var=0
        count=0
        max1=0
        pos=0
        flag=0
        for i in nums:
            if(i==1):
                flag=1
                if(var==1):
                    pos=pos+1
                count=count+1
                max1=max(count,max1)
            elif(i==0 and var==1):
                count=pos
                pos=0
            else:
                if(flag==1):
                    if(var==0):
                        var=var+1
                    else:
                        count=pos
                
        if(max1==len(nums)):
            return(max1-1)
        return(max1)

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        deleted = False
        max_, cur_cnt, last_cnt = 0, 0, 0
        idx, size = 0, len(nums)
        
        while idx < size and nums[idx] == 0: idx += 1
        for i in range(idx, size):
            if nums[i] == 1:
                cur_cnt += 1
                max_ = max(max_, cur_cnt)
            else:
                if not deleted:
                    deleted = True
                else:
                    cur_cnt -= last_cnt
                last_cnt = cur_cnt
        
        if size == sum(nums): return size-1 #[1,1,1,1]
        return max_

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if 1 not in nums:
            return 0
        if 0 not in nums:
            return len(nums)-1
        new = []
        i = 0
        n = len(nums)
        while(i < n):
            if nums[i] == 1:
                cnt = 0
                while(i < n and nums[i] == 1):
                    cnt += 1
                    i += 1
                new.append(cnt)
            else:
                new.append(0)
                i+= 1
        mx = max(new)
        for i in range(1,len(new)-1):
            if new[i] == 0:
                mx = max(mx,new[i-1] + new[i+1])
        return mx
                
                
        


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if len(nums) < 1:
            return 0
        
        res = 0
        logs = []
        
        for x in nums:
            if x==0:
                logs.append(res)
                res=0
            else:
                res+=1
        logs.append(res)
        if len(logs) == 1:
            return max(0, logs[0]-1)
    
        return max([logs[i]+logs[i+1] for i in range(len(logs)-1)])

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if sum(nums) >= len(nums) - 1:
            return len(nums) - 1
        
        l = 0
        while nums[l] == 0:
            l += 1
            if l == len(nums):
                return 0
        
        
        r = l + 1
        sum_total = nums[l]
        res = 0
        #print(r)
        for r in range(r, len(nums)):
            sum_total += nums[r]
            #print(l)
            if sum_total == r - l - 1:
                res = max(res, sum_total)
                while sum_total < r - l:
                    sum_total -= nums[l]
                    l += 1
          
        return max(res, sum_total)
                 


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if len(nums)<2:
            return 0
        len1_prev=0
        len1=0
        i=0
        res=0
        zc=0#number of zeros in the middle
        while i<len(nums):
            if nums[i]==1:
                len1+=1
            else:
                res=max(res,len1+len1_prev)
                if zc==0:
                    len1_prev=len1
                    len1=0
                    zc=1
                elif zc==1:
                    if len1>0:
                        len1_prev=len1
                        len1=0
                        zc=1
                    else:
                        len1=0
                        len1_prev=0
                        zc=0
            i+=1
                    
                    
        res=max(res,len1+len1_prev)
        res=min(len(nums)-1,res)
        
        return res
                    
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        '''
        DP
        '''
        
        n = len(nums)
        if sum(nums) == n: return n - 1
        
        dp = [[0 for x in range(len(nums))] for y in range(2)]
        
        dp[0][0] = 1 if nums[0] == 1 else 0
        
        for i in range(1, len(nums)):
            if nums[i] == 0:
                dp[0][i] = 0
                #basically \"takes\" the previous run of ones
                dp[1][i] = dp[0][i-1]
                
            else:
                dp[0][i] = dp[0][i-1] +1
                dp[1][i] = dp[1][i-1] +1
        
        # print(dp)
        return max([i for x in dp for i in x])
        
        
        
        
        
        
        
#         '''
#         sliding window
#         '''
        
#         previousRun = 0
#         currentRun = 0
#         best = 0
#         sawZero = False
        
        
#         for n in nums:
#             if n == 0:
#                 previousRun = currentRun
#                 currentRun = 0
#                 sawZero = True
#             else:
#                 currentRun += 1
#                 best = max(best, previousRun+currentRun)
#         if sawZero == False:
#             best -= 1
#         return best


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        max_len = 0
        zero_seen = False
        for i in range(len(nums)):
            length = 0
            if nums[i] == 0:
                zero_seen = True
                l,r = i-1, i+1
                while l >= 0 and nums[l] == 1:
                    length += 1
                    l -=1
                while r < len(nums) and nums[r] == 1:
                    length += 1
                    r += 1
                max_len = max(max_len, length)
        
        return max_len if zero_seen else len(nums)-1

class Solution:
    def longestSubarray(self, a: List[int]) -> int:
        ones = 0
        old_ones = 0
        maxlen = 0
        n = len(a)
        for i in range(n):
            if a[i]==1: 
                ones+=1
                maxlen = max(maxlen,ones+old_ones)
            else:
                old_ones = ones
                ones = 0

        return maxlen if ones<n else n-1

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        seq = [0]
        prev = 0
        res = 0
        
        for n in nums:
            if n:
                seq[-1] += 1
                res = max(prev + seq[-1], res)
                
            else:
                prev = seq[-1]
                seq.append(0)
                
        if len(seq) == 1:
            res -= 1
        
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        prev, res, curr = 0, 0, 0
        for i in range(len(nums)):
            if nums[i] == 1:
                curr += 1
            else:
                if i < len(nums) - 1 and nums[i + 1] != 0:
                    prev = curr
                else:
                    prev = 0
                curr = 0
            res = max(res, curr + prev)
        if res == len(nums):
            res -= 1
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        s = []; i=0
        while i < (len(nums)):
            if nums[i] == 0:
                s.append(0)
                i+=1
            else:
                j = i;cnt = 0
                while j<len(nums) and nums[j] == 1:
                    cnt+=1
                    j+=1
                s.append(cnt)
                i = j
        print(s)
        if s[0] == len(nums):
            return len(nums)-1
        maxYet = max(s[0],s[len(s)-1])
        for i in range(1,len(s)-1):
            if s[i] == 0:
                maxYet = max(maxYet, s[i-1]+s[i+1])
            else:
                maxYet = max(maxYet,s[i])
        return maxYet
            
                


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        z=[0]
        a=0
        c=0
        if nums.count(1)==len(nums):
            return len(nums)-1
        for i in range(len(nums)):
            if a==1 and nums[i]==0:
                z.append(c)
                c=(i)-(l+1)
                a=1
                l=i
            elif nums[i]==0:
                a=a+1
                l=i
            elif nums[i]==1:
                c=c+1
        z.append(c)
        return max(z)
                


import re
import numpy as np
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        nums = np.array(nums)
        zeros_ = np.where(nums == 0)[0]
        if zeros_.tolist():
            temp = 0
            for ind in zeros_:
                ind_ = max([ind-1,0])
                ind__ = min([ind+1, len(nums)-1])
                count_ = 0
                count__ = 0
                if nums[ind_] == 1:
                    while ind_>=0 and nums[ind_] == 1:
                        count_ +=1
                        ind_ -=1
                if nums[ind__]==1:
                    while ind__<len(nums) and nums[ind__] == 1:
                        count__ +=1
                        ind__ +=1
                temp = max([count_+count__, temp])
            return temp
        elif len(zeros_) == len(nums):
            return 0
        else:
            return len(nums)-1          
        
            


import re
import numpy as np
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        nums = np.array(nums)
        zeros_ = np.where(nums == 0)[0]
        if zeros_.tolist():
            temp = []
            for ind in zeros_:
                ind_ = max([ind-1,0])
                ind__ = min([ind+1, len(nums)-1])
                count_ = 0
                count__ = 0
                if nums[ind_] == 1:
                    while ind_>=0 and nums[ind_] == 1:
                        count_ +=1
                        ind_ -=1
                if nums[ind__]==1:
                    while ind__<len(nums) and nums[ind__] == 1:
                        count__ +=1
                        ind__ +=1
                temp.append(count_+count__)
            return max(temp)
        elif len(zeros_) == len(nums):
            return 0
        else:
            return len(nums)-1          
        
            


import re
import numpy as np
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        nums = np.array(nums)
        zeros_ = np.where(nums == 0)[0]
        if zeros_.tolist():
            temp = []
            for ind in zeros_:
                ind_ = max([ind-1,0])
                ind__ = min([ind+1, len(nums)-1])
                count_ = 0
                count__ = 0
                if nums[ind_] == 1:
                    while ind_>=0 and nums[ind_] == 1:
                        count_ +=1
                        ind_ -=1
                if nums[ind__]==1:
                    while ind__<len(nums) and nums[ind__] == 1:
                        count__ +=1
                        ind__ +=1
                temp.append(count_+count__)
            return max(temp)
        elif np.sum(nums) == 0:
            return 0
        else:
            return len(nums)-1
            
        # sumnums = sum(nums)
        # if sumnums==len(nums):
        #     return sumnums-1
        # elif sumnums ==0:
        #     return 0
        # elif sumnums == 1:
        #     return 1
        # else:
        #     temp = []
        #     for i in range(len(nums)):
        #         temp1 = [nums[i]]
        #         for j in range(i+1, len(nums)):
        #             if sum(temp1+[nums[j]])>=len(temp1):
        #                 temp1.append(nums[j])
        #             else:
        #                 break
        #         temp.append(temp1)
        #     return max([len(x) for x in temp])-1                
        
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        i = 0
        ints = []
        while i < len(nums):
            start = i
            end = i
            while i < len(nums) and nums[i] == 1:
                i += 1
                end += 1
                
            if start != end:
                ints.append((start, end))
                
            i += 1
            
        if len(ints) == 1:
            diff = ints[0][1] - ints[0][0]
            if diff == len(nums): return diff - 1
            else: return diff
        elif not ints:
            return 0
            
        max_ones = 0
        for seq in range(len(ints) - 1):
            seq1 = ints[seq]
            seq2 = ints[seq + 1]
            
            length = None
            if seq2[0] - seq1[1] == 1:
                length = (seq1[1] - seq1[0]) + (seq2[1] - seq2[0])
            else:
                length = max(seq1[1] - seq1[0], seq2[1] - seq2[0])
                
            if length > max_ones:
                max_ones = length
                
        return max_ones
                


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        n = len(nums)
        prev = 0
        cnt = 0
        pmax = 0
        for i in range (0,n):
            if nums[i] == 1:
                cnt += 1
            else:
                prev = cnt
                cnt = 0
                
            maxm = prev + cnt
            if maxm > pmax:
                pmax = maxm
                
        if cnt == n:
            return (n-1)
        else:
            return maxm if maxm > pmax else pmax

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        start = 0
        sliding_window_counter = collections.Counter()
        result = 0

        for end in range(len(nums)):
            sliding_window_counter[nums[end]] += 1

            while sliding_window_counter[0] > 1:
                sliding_window_counter[nums[start]] -= 1
                start += 1
            result = max(result, end - start)

        return result


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        l = 0
        r = 0
        zeros = 0
        res = 0
        while r < len(nums):
            if nums[r] == 0:
                zeros += 1
            while zeros > 1:
                if nums[l] == 0:
                    zeros -= 1
                l += 1
            res = max(res, r-l)
            r += 1
        return res

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        l = 0 
        r = 0
        earliest_one = float('inf')
        earliest_zero = float('inf')
        zeros = 1
        max_len = 0
        while(r < len(nums)):
            zeros -= nums[r] == 0
            if(zeros < 0):
                zeros += nums[l] == 0
                l += 1
            r += 1
        return r - l - 1
        
        '''#queue kind of slow
        l = 0
        r = 0
        max_len = 0
        zeros = 0
        queue = []
        while(r < len(nums)):
            if(nums[r] == 0 and zeros < 1):
                zeros = 1
                queue.append(nums[r])
                max_len = max(max_len, len(queue))
                r += 1
            elif(nums[r] == 0 and zeros == 1):
                if(queue[0] == 0):
                    #zero in front
                    while(len(queue) > 0 and queue[0] == 0):
                        queue.pop(0)
                #zero in the middle
                else:
                    while(len(queue) > 0 and queue[0] == 1):
                        queue.pop(0)
                    queue.pop(0)
                queue.append(nums[r])
                max_len = max(max_len, len(queue))
                r += 1
            elif(nums[r] == 1):
                queue.append(nums[r])
                max_len = max(max_len, len(queue))
                r += 1
        return max_len-1'''

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
#         if len(nums) == 1:
#             return 0
#         ones = []
#         count = 0
        
#         for num in nums:
#             if num == 1:
#                 count += 1
#             else:
#                 if count != 0:
#                     ones.append(count)
#                 ones.append(0)
#                 count = 0
        
#         if count != 0:
#             ones.append(count)
            
#         print(ones)
        
#         if len(ones) == 1:
#             return max(ones) - 1
#         m = max(ones)
        
#         for i in range(1, len(ones) - 1):
#             if ones[i] == 0:
#                 m = max([m, ones[i - 1] + ones[i + 1]])
                
#         return m

        i, r = 0, 1
    
        for j in range(len(nums)):
            if nums[j] == 0:
                r -= 1
                
            if r < 0:
                print('yes')
                if nums[i] == 0:
                    r += 1
                i += 1
                
        return j - i


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        s = []; i=0
        while i < (len(nums)):
            if nums[i] == 0:
                s.append(0)
                i+=1
            else:
                j = i;cnt = 0
                while j<len(nums) and nums[j] == 1:
                    cnt+=1
                    j+=1
                s.append(cnt)
                i = j
        # print(s)
        if s[0] == len(nums):
            return len(nums)-1
        maxYet = max(s[0],s[len(s)-1])
        for i in range(1,len(s)-1):
            if s[i] == 0:
                maxYet = max(maxYet, s[i-1]+s[i+1])
            else:
                maxYet = max(maxYet,s[i])
        return maxYet
            
                


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        # here k = 1
        w_start = 0
        d = {}
        max_len = 0
        case = 0
        for i in range(0,len(nums)):
            c = str(nums[i])
            if c not in d:
                d[c]=0
            d[c]+=1
            if str(0) in d:
                while(d[str(0)]>1):
                    t = str(nums[w_start])
                    d[t]-=1
                    w_start+=1
                    case=1
            max_len = max(max_len, i-w_start+1-case)
            case = 0
        return max_len-1


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        prev = 0
        prev_zero = 0
        result = float('-inf')
        boolean = False
        count = 0
        for i in range(len(nums)):
            if nums[i] == 0:
                boolean = True
                count+= 1
                if count == 2:
                    count-= 1
                    prev = prev_zero + 1
                prev_zero = i
                
            result = max(result,i - prev)
        
        return result if boolean == True else len(nums)-1
            
            


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        
        if 0 in nums and 1 in nums:
            longest = 0
            i = nums.index(0)
            
            while True:
                
                    
                if 0 in nums[:i][::-1]:
                    left_side = nums[:i][::-1].index(0)     

                else:
                            
                    left_side = len(nums[:i][::-1])
                
                    
                if 0 in nums[i+1:]:
                    right_side = nums[i+1:].index(0)
                   
                else:
                     right_side = len(nums[i+1:])


                longest = max(left_side + right_side , longest) 

                try:
                    i = nums[i + 1:].index(0) + i + 1
                except:
                    break
            
            return longest

        elif sum(nums)==0: # all zeros
            return 0


        elif sum(nums)==len(nums): # all 1s
            return(len(nums) - 1)


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        arr = []
        count = 0
        for i in range(len(nums)):
            if nums[i] == 1:
                count += 1
            elif nums[i] == 0:
                arr.append(count)
                count = 0
        arr.append(count)
        if len(arr) == 1:
            return arr[0]-1
        maxi = 0
        for j in range(1, len(arr)):
            maxi = max(maxi, arr[j-1] + arr[j])
        return maxi


class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        if 0 not in nums:
            return len(nums) - 1

        arr = [0]
        count, flag = 0, 0
        for idx, num in enumerate(nums):
            if num == 0:
                if flag == 1:
                    arr.append(count)
                    count = 0
                arr.append(0)
                flag = 0
            elif num == 1:
                count += 1
                flag = 1
            if idx == len(nums) - 1:
                arr.append(count)
        arr.append(0)

        maxSum = 0
        for i in range(1, len(arr) - 1):
            if arr[i] == 0:
                maxSum = max(maxSum, arr[i-1] + arr[i+1])

        return maxSum