<p>You are given a <strong>0-indexed</strong> binary string <code>s</code> and two integers <code>minJump</code> and <code>maxJump</code>. In the beginning, you are standing at index <code>0</code>, which is equal to <code>&#39;0&#39;</code>. You can move from index <code>i</code> to index <code>j</code> if the following conditions are fulfilled:</p>

<ul>
	<li><code>i + minJump &lt;= j &lt;= min(i + maxJump, s.length - 1)</code>, and</li>
	<li><code>s[j] == &#39;0&#39;</code>.</li>
</ul>

<p>Return <code>true</code><i> if you can reach index </i><code>s.length - 1</code><i> in </i><code>s</code><em>, or </em><code>false</code><em> otherwise.</em></p>

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

<pre>
<strong>Input:</strong> s = &quot;<u>0</u>11<u>0</u>1<u>0</u>&quot;, minJump = 2, maxJump = 3
<strong>Output:</strong> true
<strong>Explanation:</strong>
In the first step, move from index 0 to index 3. 
In the second step, move from index 3 to index 5.
</pre>

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

<pre>
<strong>Input:</strong> s = &quot;01101110&quot;, minJump = 2, maxJump = 3
<strong>Output:</strong> false
</pre>

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

<ul>
	<li><code>2 &lt;= s.length &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>
	<li><code>s[0] == &#39;0&#39;</code></li>
	<li><code>1 &lt;= minJump &lt;= maxJump &lt; s.length</code></li>
</ul>

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        def add_points(point, k, s):
            if point+k < len(s) and point+k not in done and s[point+k:point+k+1] == '0':
                stack.append(point+k)
                done.append(point+k)
                return True
            return False    

        def check_ones(s,x):
            for i in range(s.find('1'), len(s) - x):
                if s[i:i+x].find('0') == -1:
                    return False
            return True        

        def check_zeros(s, min1, max1):    
            for k in range(min1, max1+1):
                print(len(s)-1,k, min1, max1)
                if (len(s) - 1) % k ==0:
                    return True
            return False        

        stack = []
        done = []
        point = 0
        if s[-1] == '1' or minJump > len(s):
            return False
        if  len(s) > 50 and minJump <= len(s)  / 2 <= maxJump and len(s) %2 ==0 and s[len(s)//2] == '0':
            return True
#        if s.find('1') == -1 and minJump == 1: # No '1' and jump = 1
#            return True
#        print(len(s), s.count('1'), s.find('1'), maxJump)    
        if len(s) > 500 and s.count('1') >= maxJump:
            print('point d')
            res = check_ones(s, maxJump)  # check long '11111111111111111111'
            if not res:
                return False    

        if len(s) > 540 and s.find('1') == -1: # check: is possible jump a dividor for len(s)-1
            print('point f')
            res = check_zeros(s, minJump, maxJump)
            if res:
                return True    

        print('point cc')
        while stack or point == 0:
            print('---------------------')
            if stack:
                point = stack.pop()
#            print(stack, point)
            for k in range(maxJump, minJump-1, -1):
#                print('point a ', k, stack)
                res = add_points(point, k, s)
#                print(point, k+ maxJump, stack)
                if res and k+ maxJump == len(s) -1:  # check next the largest jump
                    return True 

            if len(s) - 1 in done:
                return True

            if not stack:
                return False    
        return False        
17400