为何而卷-动态规划

本文深入探讨了动态规划在解决最优化问题中的应用,如最长回文子串、跳跃游戏II、最大子数组和等。同时,介绍了回溯法在解决通配符匹配和分割回文串等问题上的策略。通过对这些经典算法的分析,揭示了动态规划和回溯法在解决复杂问题时的强大能力。
摘要由CSDN通过智能技术生成

 

5:最长回文子串

10:正则表达式匹配

22:括号生成

32:最长有效括号(hard)

class Solution {
    public int longestValidParentheses(String s) {
        if(s == null || s.length() < 2){
            return 0;
        }
        char[] chars = s.toCharArray();
        int len = chars.length, max = 0;
        Stack<Integer> ss = new Stack<>();
        for(int i = 0; i < len; i++){
            char c = chars[i];
            if(ss.isEmpty() || c == '(' || chars[ss.peek()] != '('){
                ss.push(i);
                continue;
            }
            ss.pop();
            max = Math.max(max, i - (ss.isEmpty() ? -1 : ss.peek()));
        }
        return max;

    }
}

42:接雨水

class Solution {
    public int trap(int[] height) {
        int max = 0;
        int maxIndex = 0;
        for(int i = 0; i < height.length; i++){
            if(height[i] > max){
                max = height[i];
                maxIndex = i;
            }
        }
        int left = height[0];
        int right = 0;
        int water = 0;
        for(int i = 1; i < maxIndex; i++){
            right = height[i];
            if(right > left){
                left = right;
            }else{
                water = water + left - right;
            }
        
        }
        right = height[height.length - 1];
        for(int i = height.length - 2; i > maxIndex; i--){
            left = height[i];
            if(right < left){
                right = left;
            }else{
                water = water + right - left;
            }
        
        }
        return water;


    }
}

44:通配符匹配

45:跳跃游戏II

class Solution {
    public int jump(int[] nums) {
        //maxStep表示能到达的距离
        int len = nums.length;
        int maxidx = 0;
        int right = 0;
        int count = 0;
        //为什么是len-1
        for(int i = 0; i < len-1; i++){
            maxidx = Math.max(maxidx, i + nums[i]);
            if(i == right){
                right = maxidx;
                count++;//这里不是代表成功了
            }
        }
        //成功就会退出循环
        return count;
    }
}

53:最大子数组和

class Solution {
    public int maxSubArray(int[] nums) {
        int res = nums[0];
        for(int i = 1; i < nums.length; i++){
            nums[i] = nums[i] + Math.max(0, nums[i - 1]);
            res = Math.max(res, nums[i]);
        }
        return res;
        
    }
}

55:跳跃游戏

class Solution {
    public boolean canJump(int[] nums) {
        if(nums.length == 1){
            return true;
        }
        int jumpIdx = 0;
        int lastIdx = nums.length - 1;
        for(int i = 0; i < lastIdx; i++){
            /**
            ??????????
             */
            if(i > jumpIdx){
                return false;
            }
            /**
            ??????????
             */
            jumpIdx = Math.max(jumpIdx, i + nums[i]);
            if(jumpIdx >= lastIdx){
                return true;
            }

        }
        return false;

    }
}

62:不同路径

class Solution {
    public int uniquePaths(int m, int n) {
        int dp[][] = new int[m][n];
        dp[0][0] = 0;
        for(int i = 0; i < n; i++){
            dp[0][i] = 1;
        }
        for(int i = 0; i < m; i++){
            dp[i][0] = 1;
        }
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
        return dp[m - 1][n - 1];
    }
}

63:不同路径II

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int dp[][] = new int[m][n];
        for (int i = 0; i < m; i++) {
            if (obstacleGrid[i][0] == 0){
                dp[i][0] = 1;
            }else{
                break;
            }
        }
        for (int i = 0; i < n; i++) {
            if (obstacleGrid[0][i] == 0){
                dp[0][i] = 1;
            }else{
                break;
            }
        }
        for (int i = 1; i < m; i++){
            for (int j = 1; j < n; j++){
                if (obstacleGrid[i][j] == 1){
                    dp[i][j] = 0;
                    continue;
                }else{
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[m-1][n-1];
       
    }
}

64:最小路径和

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];
        for(int i = 1; i < m; i++){
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
         for(int i = 1; i < n; i++){
            dp[0][i] = dp[0][i - 1] + grid[0][i];
        }
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[m - 1][n - 1];
    }
}

70:爬楼梯

class Solution {
    public int climbStairs(int n) {
        if(n == 1){
            return 1;
        }
        if(n == 2){
            return 2;
        }
        int prevprev = 1;
        int prev = 2;
        for(int i = 3; i <= n; i++){
            int cur = prev + prevprev;
            prevprev = prev;
            prev = cur;
        }
        return prev;

    }
}

72:编辑距离(hard)

85:最大矩形(hard)

87:扰乱字符串(hard)

91:解码方法

95:不同的二叉搜索树II

96:不同的二叉搜索树

97:交错字符串

115:不同的子序列

118:杨辉三角

119:杨辉三角II

120:三角形最小路径和

121:买卖股票的最佳时机

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0){
            return 0;
        }
        int len = prices.length;
        int maxProfit = 0;
        int minPrice = prices[0];
        for(int i = 1; i < len; i++){
            int temProfit = prices[i] - minPrice;
            if(temProfit > maxProfit){
                maxProfit = temProfit;
            }
            if(minPrice > prices[i]){
                minPrice = prices[i];
            }
        }
        return maxProfit;
    }
}

122:买卖股票的最佳时机II

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0){
            return 0;
        }
        int maxProfit = 0;
        int len = prices.length;
        for(int i = 1; i < len; i++){
            int tempProfit = prices[i] - prices[i-1];
            if(tempProfit > 0){
                maxProfit = maxProfit + tempProfit;
            }
        }
        return maxProfit;
    }
}

123:买卖股票的最佳时机III(hard)

124:二叉树中的最大路径和(hard)

class Solution {
    private int max = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        if(root == null){
            return 0;
        }
        dfs(root);
        return max;
    }
    private int dfs(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftLen = dfs(root.left);
        if(leftLen < 0){
            leftLen = 0;
        }
        int rightLen = dfs(root.right);
        if(rightLen < 0){
            rightLen = 0;
        }
        int sum = root.val + leftLen + rightLen;
        if(sum > max){
            max = sum;
        }
        return root.val + Math.max(leftLen, rightLen);
    }
}

131:分割回文串

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> resultList = new ArrayList<>();
        LinkedList<String> pathList = new LinkedList<>();
        dfs(s, resultList, pathList);
        return resultList;
    }
    private void dfs(String s, List<List<String>> resultList, LinkedList<String> pathList){
        int len = s.length();
        if(len == 0){
            resultList.add(new ArrayList<>(pathList));
            return;
        }
        for(int i = 1; i <= len; i++){
            String preStr = s.substring(0, i);
            if(!isPalindrom(preStr)){
                continue;
            }
            pathList.addLast(preStr);
            dfs(s.substring(i), resultList, pathList);
            pathList.removeLast();
        }
    }
    private boolean isPalindrom(String preStr){
        int len = preStr.length();
        if(len <= 1){
            return true;
        }
        char[] chars = preStr.toCharArray();
        int leftIdx = 0, rightIdx = len -1;
        while(leftIdx <= rightIdx){
            if(chars[leftIdx] != chars[rightIdx]){
                return false;
            }
            leftIdx++;
            rightIdx--;
        }
        return true;
    }

}

132:分割回文串II(hard)

139:单词拆分

140:单词拆分II(hard)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值