Given an array A of integers, return true if and only if it is a valid mountain array.
Recall that A is a mountain array if and only if:

A.length >= 3
There exists some i with 0 < i < A.length - 1 such that:
        
A[0] < A[1] < ... A[i-1] < A[i] 
A[i] > A[i+1] > ... > A[A.length - 1]





 
Example 1:
Input: [2,1]
Output: false


Example 2:
Input: [3,5,5]
Output: false


Example 3:
Input: [0,3,2,1]
Output: true


 
Note:

0 <= A.length <= 10000
0 <= A[i] <= 10000

Difficulty: introductory

Starter code:

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        

Solutions:
class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) <= 2:
            return False
        else:
            if A[1] < A[0]:
                return False
            is_up = True
            curr = A[0]
            for n in A[1:]:
                if n  == curr:
                    return False
                if n < curr:
                    is_up = False
                    curr = n
                if n > curr:
                    if is_up:
                        curr = n
                    else:
                        return False
            return not is_up


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        isIncreasing = True
        i = 1
        n = len(A)
        if n < 3:
            return False
        if A[1] <= A[0]:
            return False
        while i < n:
            if isIncreasing and A[i-1] < A[i]:
                i += 1
                continue
            elif A[i] < A[i-1]:
                isIncreasing = False
                i += 1
                continue
            else:
                return False
        if A[-1] >= A[-2]:
            return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        arr = A
        if len(arr) < 3:
            return False
        if arr[0] > arr[1]:
            return False
        if arr[-1] > arr[-2]:
            return False
        
        peek = None
        for i in range(1, len(arr)-1):
            if arr[i] > arr[i+1]:
                peek = i
            if peek and arr[i] < arr[i+1]:
                return False
            if arr[i] == arr[i+1] or arr[i] == arr[i-1]:
                return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        dec = 0
        n = len(A)
        if n < 3:
            return False
        else:
            for i in range(n):
                if i!= 0 and A[i] == A[i-1]:
                    return False
                elif i == 0 and A[i] > A[i+1]:
                    return False
                elif dec == 1 and A[i] > A[i-1]:
                    return False
                elif i != 0 and dec == 0 and A[i] < A[i-1]:
                    dec = 1
                elif i == (n - 1) and dec == 0:
                    return False
            return True
                
                


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:             
        N = len(A)
        if N < 3:
            return False
        i = 0
        while i < N -1:
            if(A[i]< A[i + 1]):
                i+=1
                print(i)
            else:
                break
        if (i==0 or i==N-1):
            print('***')
            return False                
        while (i<N-1):
            if (A[i] > A[i+1]):
                i += 1
                print(i)
            else:
                break
        if(i==N-1):
            return True
        else:
            print('1111')
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        length = len(A)
        if length < 3: return False
        
        prev = A[0]
        peak = -1
        
        for i in range (1, length):
            print(A[i])
            if A[i] > prev:
                if peak != -1:
                    return False
            elif A[i] == prev:
                return False
            else:
                if i == 1: 
                    return False
                peak = A[i]
            
            prev = A[i]
        
        print(peak)
        return True if peak != -1 else False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:             
        N = len(A)
        if N < 3:
            return False
        i = 0
        while i < N -1:
            if(A[i]< A[i + 1]):
                i+=1
                print(i)
            else:
                break
        if (i==0 or i==N-1):
            return False                
        while (i<N-1):
            if (A[i] > A[i+1]):
                i += 1
                print(i)
            else:
                break
        if(i==N-1):
            return True
        else:
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:             
        N = len(A)
        if N < 3:
            return False
        i = 0
        while i < N -1:
            if A[i] < A[i + 1]:
                i += 1
                print(i)
            else:
                break
        if i == 0 or i == N - 1:
            print('***')
            return False                
        while i < N - 1:
            if A[i] > A[i + 1]:
                i += 1
                print(i)
            else:
                break
        if(i==N-1):
            return True
        else:
            print('1111')
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False
        
        start = 0
        finish = len(A) 
        
       
        
        print((len(A)))
        
        for  i in range(0, len(A)-1):
            print(('i', i))
            
    
            if A[i] == A[i + 1]  :

                return False
            
            elif A[i] > A[i+1]: 
                start = i
                print(('else1', start))
                break

            
                
        for  j in range(0, len(A)-1):
            print(('j', j))       
               
                
            if A[len(A) - 1 - j] == A[len(A) - 2 - j] :
                    
                return False
                    
                    
            elif A[len(A) - 1 - j] > A[len(A) - 2 - j]:
                print(('break2' , len(A) - 1 - j, len(A) - 2 - j, A[len(A) - 1 - j], A[len(A) - 2 - j] ))
                finish = len(A) - 1 - j
                break
                
               
                
                
                
        print(('s, f', start, finish))   
        return (start == finish and start > 0 and finish < len(A) )
        



class Solution:
    
    def __init__(self):
        self.f = True
    
    def impl(self, arr, i, incr):
        self.f = incr
        if (i + 1 >= len(arr)):
            return True

        if (arr[i + 1] > arr[i] and not incr):
            return False

        elif (arr[i + 1] < arr[i] and incr):
            incr = False

        elif(arr[i + 1] == arr[i]):
            return False

        return self.impl(arr, i + 1, incr)

    def validMountainArray(self, A) -> bool:
        if (A == None or len(A) <= 2):
            return False
        if(A[1]<A[0]):
            return False
        self.f = True
        result  = self.impl(A, 0, True)
        if(self.f):
            return False
        return result
        
        
        


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if not A or len(A)< 3:
            return False
            
        l, r = 0, len(A) -1
        while l<r:
            if A[l] < A[l+1] and A[r-1] > A[r]:
                l += 1
                r -= 1
            elif A[l] < A[l+1]:
                l += 1
            elif A[r-1] > A[r]:
                r -= 1
            else:
                return False
            
            print(l, r)
        
        if l == r and l !=0 and r!= len(A)-1:
            return True
        else:
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        i=1
        N=len(A)
        if N<3:
            return False
        while(i<N and A[i]>A[i-1]):
            i +=1
        if(i==1 or i==N):
            return False
        while(i<N and A[i]<A[i-1]):
            i +=1
        return i==N  

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        
        N = len(A)
        i = 0

        # walk up
        while i+1 < N and A[i] < A[i+1]:
            i += 1

        # peak can't be first or last
        if i == 0 or i == N-1:
            return False

        # walk down
        while i+1 < N and A[i] > A[i+1]:
            i += 1

        return i == N-1


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        i = 0
        
        #walk up
        while i+1 < len(A) and A[i] < A[i+1]:
            i += 1
            
        #peak can't be first or last
        if i == 0 or i == len(A)-1:
            return False
            
        while i+1 < len(A) and A[i] > A[i+1]:
            i += 1
            
        return i == len(A) - 1
            


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) <= 2:
            return False
        else:
            t=0
            c1,c2 =0,0
            for i in range(1,len(A)-1):
                if A[i] == A[i+1]:
                    return False
                    break
                elif A[i-1] < A[i] < A[i+1] or A[i-1] > A[i] > A[i+1] or A[i-1] < A[i] > A[i+1]:
                    t +=1
                    if A[i-1] < A[i] < A[i+1]:
                        c1+=1
                    if A[i-1] > A[i] > A[i+1]:
                        c2+=1
            if t ==len(A)-2 and c1< len(A)-2 and c2< len(A)-2:
                return True
            else:
                return False
                    


#19
class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False
        nprev = A[0]
        for i in range(1,len(A)):
            if A[i] <= nprev:
                nprev = A[i-1]
                start = i 
                break
            nprev = A[i]
            if i == len(A)-1:
                return False
        
        for i in range(start,len(A)):
            if A[i] >= nprev:
                return False
            nprev = A[i]
            if start == 1 and i == len(A)- 1:
                return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False
        
        maxIndex = A.index(max(A))
        
        if (maxIndex == len(A)-1) or (maxIndex == 0):
            return False
        
        for i in range(maxIndex):
            if A[i] >= A[i+1]:
                return False
        
        for i in range(maxIndex, len(A)-1):
            if A[i] <= A[i+1]:
                return False
        
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        increasing=True
        prev = -1
        if len(A) < 3: return False
        for idx,i in enumerate(A):
            print(prev, i , increasing)
            if i == prev: return False
            if increasing:
                if i<prev:
                    increasing = False
                    if idx==1: return False
            else:
                if i>prev:
                    return False
            prev = i
        if increasing==True: return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        i = 0
        while i + 1 < len(A) and A[i + 1] > A[i]:
            i += 1
        if i == 0 or i == len(A) - 1:
            return False
        
        while i + 1 < len(A) and A[i + 1] < A[i]:
            i += 1
        return i == len(A) - 1

class Solution:
    def validMountainArray(self, arr: List[int]) -> bool:
        i = 0
        l = len(arr)
        while i+1 < l and arr[i] < arr[i+1]:
            i += 1

        if i == 0 or i == l-1:
            return False

        while i+1 < l and arr[i] > arr[i+1]:
            i += 1

        return i == l-1

class Solution(object):
    def validMountainArray(self, A):
        N = len(A)
        i = 0

        # walk up
        while i+1 < N and A[i] < A[i+1]:
            i += 1

        # peak can't be first or last
        if i == 0 or i == N-1:
            return False

        # walk down
        while i+1 < N and A[i] > A[i+1]:
            i += 1

        return i == N-1


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) <= 2:
            return False
        i = 0
        N = len(A)
        while i < N and i+1<N and A[i] < A[i+1]:
            i+=1
        if i ==0 or i ==N-1:
            return False
        while i<N and i+1<N and A[i] > A[i+1]:
            i+=1
        if i==N-1:
            return True
        return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        # find max
        # everything to the left should be strictly decreasing 
        # everything to the right should be decreasing 
        m = (0,0)
        for i in range(0, len(A)):
            if A[i] > m[1]:
                m = (i, A[i])
        
        if m[0] == 0 or m[0] == len(A)-1:
            return False
        for i in range(0, m[0]-1):
            if A[i] >= A[i+1]:
                return False
        for i in range(m[0], len(A)-1):
            if A[i] <= A[i+1]:
                return False
        return True

class Solution:
    def walkUp(self, A: List[int]) -> int:
        for i, step in enumerate(A[:-1]):
            if A[i] >= A[i+1]:
                return i
        return len(A)
        
    def walkDown(self, A: List[int], top: int) -> bool:
        for i, step in enumerate(A[top:-1], start=top):
            if A[i] <= A[i+1]:
                return False
        return True
    
    def validMountainArray(self, A: List[int]) -> bool:
        top = self.walkUp(A)
        if top == 0 or top == len(A):
            return False
        return self.walkDown(A, top)
            


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False
        switch = 0
        if A[0] > A[1]:
            return False
        for i in range(2, len(A)):
            if A[i] == A[i - 1]:
                return False
            if switch == 0 and A[i] < A[i - 1]:
                switch = 1
            elif switch == 1 and A[i] > A[i - 1]:
                return False
        if switch == 0:
            return False
        return True


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False

        N = len(A)-1
        reached = False
        for i in range(N):
            if A[i] == A[i+1]:
                return False
            
            if not reached:
                if A[i] > A[i+1]:
                    if i == 0:
                        return False
                    reached = True
            else:
                if A[i] < A[i+1]:
                    return False
        return reached

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if(len(A) >= 3):
            peak = max(A)
            if(A.count(peak) == 1):
                peakInd = A.index(peak)
                incArr = A[:peakInd]
                decArr = A[peakInd+1:]
                if(len(incArr) > 0 and len(decArr) > 0):
                    for i in range(1,len(incArr)):      
                        if(incArr[i]<= incArr[i-1]):
                            return False
                    for d in range(0,len(decArr)-1):
                        if(decArr[d]<= decArr[d+1]):
                            return False        
                    return True
                else:
                    return False
            else:
                return False
        else:
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        strict_inc = False
        strict_dec = False
        if len(A) > 2:
            for i in range(1,len(A)):
                if A[i] > A[i-1]:
                    if strict_dec:
                        return False
                    strict_inc = True
                    
                elif A[i] < A[i-1]:
                    strict_dec = True
                else:
                    return False
            if strict_inc and strict_dec:
                return True
            else:
                return False
        else:
            return False


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        
        if len(A) in [0,1,2] :
            return False
        max_ele = max(A)
        if A.count(max_ele) > 1 :
            return False
        
        index = A.index(max_ele)
        
        if index == len(A) - 1 or index == 0:
            return False
        
        for i in range(0,index) :
            print(('values',A[i],A[i+1]))
            print(('index',i,i+1))
            if not(A[i] < A[i+1]) :
                print('trig1')
                return False
        
        for i in range(len(A)-1,index+1,-1) :
            print('hi')
            if not(A[i] < A[i-1]) :
                print('trig2')
                return False
        return True
            
            
        
       
            
            

            
            
            
        
      
                    
                
                
                
        


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        i, j = 0, len(A) - 1
        while i < j:
            if A[i] < A[i + 1]:
                i += 1
            if A[j] < A[j - 1]:
                j -= 1
            elif i + 1 >= len(A) or A[i] >= A[i + 1]:
                break
        return i == j and 0 < i < len(A) - 1

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        
        if len(A) < 3:
            return False
        
        diffs = [A[i+1] - A[i] for i in range(len(A)-1)]
        
        if 0 in diffs or diffs[0] < 0:
            return False
        
        peak = False
        for i in range(len(diffs)-1):
            if diffs[i+1]/abs(diffs[i+1]) != diffs[i]/abs(diffs[i]):
                if peak == False:
                    peak = True
                else:
                    return False
        return peak     #catches the case where no peak


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3:
            return False
        
        for i in range(len(A)-1):
            if A[i] >= A[i+1]:
                break
        for j in range(-1, -len(A), -1):
            if A[j] >= A[j-1]:
                break
        return i == len(A) + j

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        n = len(A)
        if n < 3:
            return False
        changes = 0
        is_increasing = False
        is_decreasing = False
        for i in range(0, n-1):
            if changes == 0:    
                if A[i] > A[i+1]:
                    changes += 1
                    is_decreasing = True
                elif A[i] == A[i+1]:
                    changes += 1
                else:
                    is_increasing = True
            elif changes == 1:
                if A[i] <= A[i+1]:
                    changes += 1
                else:
                    is_decreasing = True
            else:
                return False
        return changes < 2 and is_decreasing and is_increasing
                
                    
            


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        arr=A
        i=1
        while i<len(arr):
            if arr[i-1]<arr[i]:
                i+=1
            else:
                break
        if i==1 or i==len(arr):
            return False
        while i<len(arr):
            if arr[i-1]>arr[i]:
                i+=1
            else:
                return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) < 3: return False
        up = True
        for i in range(1, len(A)):
            if A[i] == A[i-1]:
                # flat                 
                return False
            if up:
                # going up
                if A[i] < A[i-1]:
                    # going down
                    if i == 1:
                        # starting down is not valid
                        return False
                    up = False
            else:
                # going down
                if A[i] > A[i-1]:
                    # going back up after down is not mountain
                    return False
        return not up

class Solution(object):
    def validMountainArray(self, A):
        N = len(A)
        i = 0

        # walk up
        while i+1 < N and A[i] < A[i+1]:
            i += 1

        # peak can't be first or last
        if i == 0 or i == N-1:
            return False

        # walk down
        while i+1 < N and A[i] > A[i+1]:
            i += 1

        return i == N-1

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        
        if len(A) < 3:
            return False
        
        if A[0] > A[1]:
            return False
        
        decreasing = False
        last = A.pop(0)
        
        while A:
            
            new = A.pop(0)
            print((new, last, decreasing))
            if new == last:
                return False
            
            if new > last and decreasing:
                print('early')
                return False
            
            if new < last and not decreasing:
                decreasing = True
                
            last = new
            
        return decreasing
            
            
        


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        n = len(A)
        if n < 3: return False
        i = 0
        
        while i < n-1 and A[i] < A[i+1]:
            i += 1
        
        if i == 0 or i == n-1:
            # peak at beginning or end
            return False
        
        while i < n-1 and A[i] > A[i+1]:
            i += 1
        
        if i != n-1:
            return False
        return True

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
      passedPeak = False
      
      if len(A) <= 2 or A[0] > A[1]: return False
      
      for i in range(len(A)-1):
        if A[i] == A[i+1]: return False

        if passedPeak == True and A[i] < A[i+1]: return False
            
        if passedPeak == False and A[i] > A[i+1]:
            passedPeak = True

      if passedPeak: return True
      else: return False


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        inflection = None
        if len(A) > 3:
            for i in range(0,len(A)- 1):
                if inflection is not None:
                    if A[i] < A[i+1]:
                        return False
                else:
                    if A[i] > A[i+1]:
                        inflection = i
            
            print(inflection,A[0:inflection],A[inflection:])
            
            if inflection is not None:
                if len(A[0:inflection]) and len(A[inflection:]):
                    if len(set(A[0:inflection]))+len(set(A[inflection:])) == len(A):
                        return True
                    else:
                        return False
                else:
                    return False
                    print(set(A[0:inflection]),len(A[0:inflection]),set(A[inflection:]),len(A[inflection:]))
                    return False
            else:
                return False
        elif len(A) == 3:
            if A[0] < A[1] and A[1] > A[2]:
                return True
            else:
                return False
        else:
            return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        
        N = len(A)-1
        i = 0

        # walk up
        while i < N and A[i] < A[i+1]:
            i += 1

        # peak can't be first or last
        if i == 0 or i == N:
            return False

        # walk down
        while i < N and A[i] > A[i+1]:
            i += 1

        return i == N


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if(len(A)<3):
            return False
        elif(A.index(max(A))==0 or A.index(max(A))==(len(A)-1)):
            return False
        else:
            for i in range(A.index(max(A))):
                if(A[i]>=A[i+1]):
                    return False
            for i in range(A.index(max(A)),len(A)-1):
                if(A[i]<=A[i+1]):
                    return False
            return True


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        climb = True
        cs = 0
        fs = 0
        for i in range(1, len(A)):
            if climb == True:
                if A[i] > A[i-1]:
                    cs += 1
                    continue
                elif A[i] == A[i-1]:
                    return False
                else:
                    climb = False
            if climb == False:
                if A[i] < A[i-1]:
                    fs += 1
                    continue
                else:
                    return False
        if cs > 0 and fs > 0:
            return True
        return False

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if(len(A)<3):
            return False
        i = 1
        while(i<len(A) and A[i]>A[i-1]):
            i+=1
        if(i==1 or i==len(A)):
            return False
        
        while(i<len(A) and A[i]<A[i-1]):
            i+=1
        return i==len(A)

class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if len(A) == 0 or len(A) == 1:
            return False
        
        idx = 0
        
        while (idx < len(A) - 1 and A[idx] < A[idx+1]):
            idx += 1
        if idx == 0 or idx == len(A) - 1:
            return False
        while (idx < len(A) - 1 and A[idx] > A[idx+1]):
            idx += 1
        
        print((idx, len(A)))
        return idx == len(A) - 1


class Solution:
    def validMountainArray(self, A: List[int]) -> bool:
        if not A or len(A)<=2:
            return False
        increase = -1        
        for i in range(1, len(A)):
            if A[i] > A[i-1] and increase == -1:
                increase = 1
            if A[i] > A[i-1] and increase == 1:
                continue
            elif A[i] < A[i-1] and increase == 1:
                increase = 0
            elif A[i] < A[i-1] and increase == 0:
                continue
            else:
                return False
        if increase != 0:
            return False
        return True