<p>You are given a <strong>0-indexed</strong> binary string <code>s</code> of length <code>n</code> on which you can apply two types of operations:</p>

<ul>
	<li>Choose an index <code>i</code> and invert all characters from&nbsp;index <code>0</code> to index <code>i</code>&nbsp;(both inclusive), with a cost of <code>i + 1</code></li>
	<li>Choose an index <code>i</code> and invert all characters&nbsp;from&nbsp;index <code>i</code> to index <code>n - 1</code>&nbsp;(both inclusive), with a cost of <code>n - i</code></li>
</ul>

<p>Return <em>the <strong>minimum cost </strong>to make all characters of the string <strong>equal</strong></em>.</p>

<p><strong>Invert</strong> a character means&nbsp;if its value is &#39;0&#39; it becomes &#39;1&#39; and vice-versa.</p>

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

<pre>
<strong>Input:</strong> s = &quot;0011&quot;
<strong>Output:</strong> 2
<strong>Explanation:</strong> Apply the second operation with <code>i = 2</code> to obtain <code>s = &quot;0000&quot; for a cost of 2</code>. It can be shown that 2 is the minimum cost to make all characters equal.
</pre>

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

<pre>
<strong>Input:</strong> s = &quot;010101&quot;
<strong>Output:</strong> 9
<strong>Explanation:</strong> Apply the first operation with i = 2 to obtain s = &quot;101101&quot; for a cost of 3.
Apply the first operation with i = 1 to obtain s = &quot;011101&quot; for a cost of 2. 
Apply the first operation with i = 0 to obtain s = &quot;111101&quot; for a cost of 1. 
Apply the second operation with i = 4 to obtain s = &quot;111110&quot; for a cost of 2.
Apply the second operation with i = 5 to obtain s = &quot;111111&quot; for a cost of 1. 
The total cost to make all characters equal is 9. It can be shown that 9 is the minimum cost to make all characters equal.
</pre>

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

<ul>
	<li><code>1 &lt;= s.length == n &lt;= 10<sup>5</sup></code></li>
	<li><code>s[i]</code> is either <code>&#39;0&#39;</code> or <code>&#39;1&#39;</code></li>
</ul>

class Solution:
    def minimumCost(self, s: str) -> int:

        # flip all values to 0 or to 1
        # due to our choices, it is more wise to only split up to half of one string
        # focus on two problems -> getting half of S + other half of S both to 0s OR 1s
        # if our target is 1 and we have a 0, we keep track of the last 0 -> 1 -> 0, sum up these indicies + 1
        # [1, 2, 3] == 6
        # [1, 2] == 3
        # based on the length of these swaps == number of flips -- look at the index of our last digit
        # if they match, then they are both the same, if not, we have to add 1 to our result to flip the entire string to be the same
        # if we have an odd length string, pair it with whichever one it matches

        if len(s) == 1:
            return 0

        split = len(s) // 2

        if len(s) % 2 == 1 and len(s) >= 3:
            m = len(s) // 2
            if s[m-1] == s[m]:
                split = m + 1
            else:
                split = m
        
        half1, half2 = s[:split], s[split:]

        def countInversions(s, target):
            flipIdxs = []
            prev = s[0]
            idx = 0

            while idx < len(s):
                while idx < len(s) and s[idx] == prev:
                    idx += 1
                
                flipIdxs.append(idx - 1)
                if idx < len(s):
                    prev = s[idx]

            if len(flipIdxs) == 1:
                flipped = str(1 - int(s[flipIdxs[-1]]))

                if flipped == target:
                    return sum(flipIdxs) + len(flipIdxs)
                
                return 0
            
            else:
                flippedOne = str(1 - int(s[flipIdxs[-1]]))
                flippedTwo = str(1 - int(s[flipIdxs[-2]]))

                if flippedOne == target:
                    return sum(flipIdxs) + len(flipIdxs)
                
                else:
                    return sum(flipIdxs[:-1]) + len(flipIdxs) - 1

        allOnes = countInversions(half1, "1") + countInversions(half2[::-1], "1")
        allZeroes = countInversions(half1, "0") + countInversions(half2[::-1], "0")

        return min(allOnes, allZeroes)
            
        

        
223