LeetCode【Dynamic Planning】

   public String longestPalindrome(String s) {
        String res = "";
        for (int i = 0; i < s.length(); i++) {
            // 以 s[i] 为中心的最长回文子串
            String s1 = palindrome(s, i, i);
            // 以 s[i] 和 s[i+1] 为中心的最长回文子串
            String s2 = palindrome(s, i, i + 1);
            // res = longest(res, s1, s2)
            res = res.length() > s1.length() ? res : s1;
            res = res.length() > s2.length() ? res : s2;
        }
        return res;
    }

    String palindrome(String s, int l, int r) {
        // 防止索引越界
        while (l >= 0 && r < s.length()
                && s.charAt(l) == s.charAt(r)) {
            // 向两边展开
            l--;
            r++;
        }
        // 返回以 s[l] 和 s[r] 为中心的最长回文串
        return s.substring(l + 1, r);
    }

  public List<String> result = new LinkedList<>();
    public List<String> generateParenthesis(int n) {
        StringBuffer sb = new StringBuffer();
        blackTrack(n,n,result,sb);
        return result;
    }

    private void blackTrack(int left, int right, List<String> result, StringBuffer sb) {
        if (left > right){
            return;
        }
        if (left < 0 || right < 0){
            return;
        }
        if (left == 0 && right == 0){
          result.add(sb.toString());
        }
        sb.append("(");
        blackTrack(left-1,right,result,sb);
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        blackTrack(left,right-1,result,sb);
        sb.deleteCharAt(sb.length()-1);
    }

    public int longestValidParentheses(String s) {
       Stack<Integer> stack = new Stack<>();
        int[] dp = new int[s.length()+1];
        for (int i = 0; i < s.length(); i++){
            if (s.charAt(i) == '('){
                stack.push(i);
                dp[i+1] = 0;
            }else {
                if (!stack.isEmpty()){
                    int leftIndex = stack.pop();
                    int len = 1 + i - leftIndex + dp[leftIndex];
                    dp[i+1] = len;
                }else {
                    dp[i+1] = 0;
                }
            }
        }
        int res = 0;
        for (int i = 0; i < dp.length; i++){
            res = Math.max(res,dp[i]);
        }
        return res;
    }

 public int trap(int[] height) {
        if (height.length == 0) {
            return 0;
        }
        int n = height.length;
        int res = 0;
        // 数组充当备忘录
        int[] l_max = new int[n];
        int[] r_max = new int[n];
        // 初始化 base case
        l_max[0] = height[0];
        r_max[n - 1] = height[n - 1];
        // 从左向右计算 l_max
        for (int i = 1; i < n; i++)
            l_max[i] = Math.max(height[i], l_max[i - 1]);
        // 从右向左计算 r_max
        for (int i = n - 2; i >= 0; i--)
            r_max[i] = Math.max(height[i], r_max[i + 1]);
        // 计算答案
        for (int i = 1; i < n - 1; i++)
            res += Math.min(l_max[i], r_max[i]) - height[i];
        return res;
    }

 public int jump(int[] nums) {
        int n = nums.length;
        int end = 0, farthest = 0;
        int jumps = 0;
        for (int i = 0; i < n - 1; i++) {
            farthest = Math.max(nums[i] + i, farthest);
            if (end == i) {
                jumps++;
                end = farthest;
            }
        }
        return jumps;
    }

   public int maxSubArray(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        int[] dp = new int[n];
        // base case
        // 第一个元素前面没有子数组
        dp[0] = nums[0];
        // 状态转移方程
        for (int i = 1; i < n; i++) {
            dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
        }
        // 得到 nums 的最大子数组
        int res = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            res = Math.max(res, dp[i]);
        }
        return res;
    }

  public boolean canJump(int[] nums) {
       int n = nums.length;
        int farthest = 0;
        for (int i = 0; i < n - 1; i++) {
            // 不断计算能跳到的最远距离
            farthest = Math.max(farthest, i + nums[i]);
            // 可能碰到了 0,卡住跳不动了
            if (farthest <= i) {
                return false;
            }
        }
        return farthest >= n - 1;
    }

public int uniquePaths(int m, int n) {
    return dp(m - 1, n - 1);
}

// 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
int dp(int x, int y) {
    if (x == 0 && y == 0) {
        return 1;
    }
    if (x < 0 || y < 0) {
        return 0;
    }
    // 状态转移方程:
    // 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
    return dp(x - 1, y) + dp(x, y - 1);
}

public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        // 数组索引偏移一位,dp[0][..] dp[..][0] 代表 obstacleGrid 之外
        // 定义:到达 obstacleGrid[i][j] 的路径条数为 dp[i-1][j-1]
        int[][] dp = new int[m + 1][n + 1];
        // base case:如果没有障碍物,起点到起点的路径条数就是 1
        dp[1][1] = obstacleGrid[0][0] == 1 ? 0 : 1;

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (i == 1 && j == 1) {
                    // 跳过 base case
                    continue;
                }
                if (obstacleGrid[i - 1][j - 1] == 1) {
                    // 跳过障碍物的格子
                    continue;
                }
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        // 返回到达 obstacleGrid[m-1][n-1] 的路径数量
        return dp[m][n];
    }

</

Guess you like

Origin blog.csdn.net/qq_50156012/article/details/124889854