|
| 1 | +# Time: O(m * n) |
| 2 | +# Space: O(n) |
| 3 | + |
| 4 | +import collections |
| 5 | + |
| 6 | + |
| 7 | +# dp, optimized from solution2 |
| 8 | +class Solution(object): |
| 9 | + def hasValidPath(self, grid): |
| 10 | + """ |
| 11 | + :type grid: List[List[str]] |
| 12 | + :rtype: bool |
| 13 | + """ |
| 14 | + if (len(grid)+len(grid[0])-1)%2: |
| 15 | + return False |
| 16 | + dp = [[float("inf"), float("-inf")] for _ in xrange(len(grid[0])+1)] |
| 17 | + for i in xrange(len(grid)): |
| 18 | + dp[0] = [0, 0] if not i else [float("inf"), float("-inf")] |
| 19 | + for j in xrange(len(grid[0])): |
| 20 | + d = 1 if grid[i][j] == '(' else -1 |
| 21 | + dp[j+1] = [min(dp[j+1][0], dp[j][0])+d, max(dp[j+1][1], dp[j][1])+d] |
| 22 | + if dp[j+1][1] < 0: |
| 23 | + dp[j+1] = [float("inf"), float("-inf")] |
| 24 | + else: |
| 25 | + dp[j+1][0] = max(dp[j+1][0], dp[j+1][1]%2) |
| 26 | + return dp[len(grid[0])][0] == 0 |
| 27 | + |
| 28 | + |
| 29 | +# Time: O((m * n) * (m + n) / 32) |
| 30 | +# Space: O(n * (m + n) / 32) |
| 31 | +# dp |
| 32 | +class Solution2(object): |
| 33 | + def hasValidPath(self, grid): |
| 34 | + """ |
| 35 | + :type grid: List[List[str]] |
| 36 | + :rtype: bool |
| 37 | + """ |
| 38 | + if (len(grid)+len(grid[0])-1)%2: |
| 39 | + return False |
| 40 | + dp = [0]*(len(grid[0])+1) |
| 41 | + for i in xrange(len(grid)): |
| 42 | + dp[0] = int(not i) |
| 43 | + for j in xrange(len(grid[0])): |
| 44 | + dp[j+1] = (dp[j]|dp[j+1])<<1 if grid[i][j] == '(' else (dp[j]|dp[j+1])>>1 |
| 45 | + return dp[-1]&1 |
0 commit comments