<p>You are given an integer array <code>target</code>. You have an integer array <code>initial</code> of the same size as <code>target</code> with all elements initially zeros.</p>

<p>In one operation you can choose <strong>any</strong> subarray from <code>initial</code> and increment each value by one.</p>

<p>Return <em>the minimum number of operations to form a </em><code>target</code><em> array from </em><code>initial</code>.</p>

<p>The test cases are generated so that the answer fits in a 32-bit integer.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> target = [1,2,3,2,1]
<strong>Output:</strong> 3
<strong>Explanation:</strong> We need at least 3 operations to form the target array from the initial array.
[<strong><u>0,0,0,0,0</u></strong>] increment 1 from index 0 to 4 (inclusive).
[1,<strong><u>1,1,1</u></strong>,1] increment 1 from index 1 to 3 (inclusive).
[1,2,<strong><u>2</u></strong>,2,1] increment 1 at index 2.
[1,2,3,2,1] target array is formed.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> target = [3,1,1,2]
<strong>Output:</strong> 4
<strong>Explanation:</strong> [<strong><u>0,0,0,0</u></strong>] -&gt; [1,1,1,<strong><u>1</u></strong>] -&gt; [<strong><u>1</u></strong>,1,1,2] -&gt; [<strong><u>2</u></strong>,1,1,2] -&gt; [3,1,1,2]
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> target = [3,1,5,4,2]
<strong>Output:</strong> 7
<strong>Explanation:</strong> [<strong><u>0,0,0,0,0</u></strong>] -&gt; [<strong><u>1</u></strong>,1,1,1,1] -&gt; [<strong><u>2</u></strong>,1,1,1,1] -&gt; [3,1,<strong><u>1,1,1</u></strong>] -&gt; [3,1,<strong><u>2,2</u></strong>,2] -&gt; [3,1,<strong><u>3,3</u></strong>,2] -&gt; [3,1,<strong><u>4</u></strong>,4,2] -&gt; [3,1,5,4,2].
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= target.length &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= target[i] &lt;= 10<sup>5</sup></code></li>
</ul>

class Solution:
    def minNumberOperations(self, target: List[int]) -> int:
        # approach: Looks like falling rain
        # Iterate over array left to right - for each node, find the node on its right where the value dips below curr node value. Focus on element left of that, which is the right 'wall'
        # [1, 2, 3, 2, 1] becomes [4, 3, 2, 3, 4]
        # then, do the same thing working from right to left to find the left 'wall'
        # [1, 2, 3, 2, 1] becomes [0, 1, 2, 1, 0]
        # then, count the values from each (maybe just one) of these that are the same... might not work actually, but try it anyway. -> 3 unique in each


        # case 2: 
        # [3, 1, 5, 4, 2] -> ltr -> [0, 4, 2, 3, 4]
        # [3, 1, 5, 4, 2] -> rtl -> [0, 0, 2, 2, 2]
        # combined by taking max -> [0, 4, 2, 3, 4]
        


        # approach 2: sensible way of doing things... also slow b/c O(n^2)
        # for each layer height, find the number of distinct zones at said height and add that to a result

        # possible approach 3: need to test... Count the sum of local maximums and subtract the sum of local minimums NOT on the edge of input

        if len(target) < 3:
            return max(target)

        def getLocalMaxes(ints):
            i = 0           
            res = []

            # refactored edge max assignment:
            if ints[i] >= ints[i+1]: # this is shit... need to do the whole skipping over elements deal
                while i < len(ints) - 1 and ints[i] == ints[i+1]:                   
                    i += 1
                if i < len(ints) - 1 and ints[i] > ints[i+1]:
                    res.append(ints[i])
                elif i == len(ints):
                    res.append(ints[i])

            if i != len(ints) - 1:

                j = len(ints) - 1
                if ints[j] >= ints[j-1]: # this is shit... need to do the whole skipping over elements deal
                    while j > 0 and ints[j] == ints[j-1]:                   
                        j -= 1
                    if ints[j] >= ints[j-1]:
                        res.append(ints[j])

            # several scenarios where we have a local max
            # 1: mid > left and mid > right
            # 2: mid_series > left and mid_series > right
            while i+2 < len(ints):
                window_left = ints[i]
                window_mid = ints[i+1]
                window_right = ints[i+2]
                if window_mid > window_left and window_mid > window_right: # condition 1: mid is greater than neighbors
                    res.append(window_mid)
                elif window_mid > window_left and window_mid == window_right: # condition 2: need to slide right over until it's greater or less than mid
                    while i+2 < len(ints)-1 and window_mid == window_right:
                        i += 1
                        window_right = ints[i+2]
                    if window_mid > window_left and window_mid > window_right: # condition 1: mid is greater than neighbors
                        res.append(window_mid)
                i+=1

            # one last check: if we haven't appended anything, the whole array must be the same character, so append it
            if len(res) == 0:
                res.append(ints[0])
            return res

        def getLocalMins(ints):
            i = 0           
            res = []

            # several scenarios where we have a local max
            # 1: mid > left and mid > right
            # 2: mid_series > left and mid_series > right
            while i+2 < len(ints):
                window_left = ints[i]
                window_mid = ints[i+1]
                window_right = ints[i+2]
                if window_mid < window_left and window_mid < window_right: # condition 1: mid is greater than neighbors
                    res.append(window_mid)
                elif window_mid < window_left and window_mid == window_right: # condition 2: need to slide right over until it's greater or less than mid
                    while i+2 < len(ints)-1 and window_mid == window_right:
                        i += 1
                        window_right = ints[i+2]
                    if window_mid < window_left and window_mid < window_right: # condition 1: mid is greater than neighbors
                        res.append(window_mid)
                i+=1
            return res


        maxes = getLocalMaxes(target)
        mins = getLocalMins(target)

        print(f"local maxes = {maxes}. local mins = {mins}")
        return sum(maxes) - sum(mins)
        
        
28200