# Coordinate

## 63 Unique Path II

Now consider if some obstacles are added to the grids. How many unique paths would there be

```python
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
    m, n = len(obstacleGrid), len(obstacleGrid[0])
    dp = [0] * n
    
    for j in range(n):
        if obstacleGrid[0][j] == 1: break
        dp[j] = 1
        
    for i in range(1, m):
        if obstacleGrid[i][0] == 1:
            dp[0] = 0
        for j in range(1, n):
            dp[j] = dp[j] + dp[j-1] if obstacleGrid[i][j] == 0 else 0
 
    return dp[n-1]
```

## Jump Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

```python
 """
 DP
 Time: O(n^2)
 Space: O(n)
 """
def canJump(self, nums: List[int]) -> bool:
     n = len(nums)
     dp = [False] * n
     dp[0] = True
    
     for i in range(n-1):
        if dp[i]:
            for jump in range(1, nums[i]+1):
                if i+jump < n:
                    dp[i+jump] = True
     return dp[-1]

 """
 Greedy
 Time: O(n)
 Space: O(1)
 """
 def jump(self, nums: List[int]) -> int:
    n = len(nums)
    max_pos = nums[0]
    
    for i in range(1, n):
        if max_pos < i:
            return False
        max_pos = max(max_pos, i+nums[i])
    return True
```

## Jump game II

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

```python
 """
 DP
 Time: O(n^2)
 Space: O(n)
 """
 def jump(self, nums: List[int]) -> int:
    n = len(nums)
    dp = [float('inf')] * n
    dp[0] = 0
    
    for i in range(n-1):
        if i == 0 or dp[i] != float('inf'):
            for jump in range(1, nums[i]+1):
                if i+jump < n:
                    dp[i+jump] = min(dp[i+jump], 1 + dp[i])
        
    return dp[-1] if dp[-1] != float('inf') else 0

 """
 Greedy
 Time: O(n)
 Space: O(1)
 """
 def jump(self, nums: List[int]) -> int:
    n = len(nums)
    if n <= 1: return 0
    
    # max position reachable from index 0
    pos_max = nums[0]
    
    # max position reachable from current jump
    cur_max = nums[0]
    count = 1
    
    for i in range(1, n):
        if cur_max < i:
            count += 1
            cur_max = pos_max
        pos_max = max(pos_max, i + nums[i])
    
    return count
```

## Magicl Vowel

A magical sub-sequence of a string S is a sub-sequence of S that contains all five vowels in order. Find the length of largest magical sub-sequence of a string S. For example, if S = aeeiooua, then aeiou and aeeioou are magical sub-sequences but aeio and aeeioua are not.

* State: S到index i, char到index j目前longest voewl string number
* Func: dp\[i]\[j] = if(s\[i]==c\[j]) max(dp\[i-1]\[j], dp\[i]\[j-1]) + 1, else max(dp\[i-1]\[j], dp\[i]\[j-1])
* Ans: dp\[m]\[n] must >= char length, otherwise return 0;             &#x20;

```java
static int longestSubsequence(String s){
    char[] chars = new char[] {'a','e','i'};
    char[] stringArr = s.toCharArray();

    int m = stringArr.length;
    int n = chars.length;

    int[][] dp = new int[m][n];

    // init
    if(chars[0] == stringArr[0]) dp[0][0] = 1;


    for(int i=1; i<m; i++) {
        for (int j = 1; j < n; j++) {
            if (stringArr[i] == chars[j]) {
                dp[i][j] = 1 + Math.max(dp[i - 1][j], dp[i][j - 1]);
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

    // answer must be as least greater or equal than char length
    return dp[m-1][n-1] < n ? 0 : dp[m-1][n-1];
}

public static void main(String[] args) {
    String s1 = "aie";
    String s2 = "aaeeie";
    String s3 = "iaeaaeiiae";
    String s4 = "eaei";

    System.out.println(longestSubsequence(s1));
    System.out.println(longestSubsequence(s2));
    System.out.println(longestSubsequence(s3));
    System.out.println(longestSubsequence(s4));
}
```
