【备战字节面试】算法特训-动态规划

240 阅读2分钟

简单粗暴,记录备战过程,持续更新

动态规则

适用场景

实战

实战1 300. 最长递增子序列

class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length <= 1){
            return 1;
        }
        int ans = 1;
        int[] dp = new int[nums.length];
        dp[0] = 1;
        for(int i = 1; i < nums.length ; i++){
            dp[i] = 1;
            for(int j = 0 ; j < i ; j++){
                if(nums[i] > nums[j]){
                    dp[i] = Math.max(dp[i],dp[j] + 1);
                }
            }
            ans = Math.max(dp[i],ans);
        }
        return ans;
    }
}

实战2 322. 零钱兑换

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp,amount+1);
        dp[0] = 0;
        for(int i = 1 ; i <= amount; i++){
            int min = amount + 1;
            for(int j = 0 ; j < coins.length; j++){
                if(i - coins[j] >= 0){
                    min = Math.min(min,dp[i-coins[j]]);
                }
            }
            dp[i] = min + 1;
        }
        return dp[amount] >= amount+1 ? -1 : dp[amount];
    }
}

实战3 1143. 最长公共子序列

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int len1 = text1.length();
        int len2 = text2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        dp[0][0] = 0;
        for(int i = 0; i < len1; i++ ){
            for(int j = 0; j < len2; j++){
                if( text1.charAt(i) == text2.charAt(j)){
                    dp[i+1][j+1] = dp[i][j] + 1;
                }else{
                    dp[i+1][j+1] = Math.max(dp[i][j+1],dp[i+1][j]);
                }
            }
        }
       return dp[len1][len2];
    }
}

实战4 72. 编辑距离

实战5 516. 最长回文子序列

class Solution {
    public int longestPalindromeSubseq(String s) {
        int len = s.length();
        int[][] dp = new int[len][len];
        // 步长1
        for(int i = 0 ; i < len; i++){
            dp[i][i] = 1;
        }
        // 步长2
        for(int i = 0 ; i < len - 1 ; i++){
            char char1 = s.charAt(i);
            char char2 = s.charAt(i+1);  
            if(char1 == char2){
                dp[i][i+1] = 2;
            }else{
                dp[i][i+1] = 1;
            }
        }
        // 步长 >= 3
        for(int step = 3 ; step <= len ; step++){
            for(int j = 0 ; j + step <= len ; j++){
                char char1 = s.charAt(j);
                char char2 = s.charAt(j+step-1);
                if(char1 == char2){
                    dp[j][j+step-1] = dp[j+1][j+step-2] + 2;
                }else{
                    dp[j][j+step-1] = Math.max( dp[j+1][j+step-1], dp[j][j+step-2]);
                }
            }
        }
        return dp[0][len-1];
    }
}

实战6 53. 最大子数组和

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

实战7 11. 盛最多水的容器

class Solution {
    public int maxArea(int[] height) {
        int left = 0 , right = height.length-1;
        int ans = 0;
        while(left < right){
            int tmp = (right-left) * Math.min(height[left],height[right]);
            ans = Math.max(ans,tmp);
            if(height[left] <= height[right]){
                left++;
            }else{
                right--;
            }
        }
        return ans;
    }
}

实战8 121. 买卖股票的最佳时机

class Solution {
    public int maxProfit(int[] prices) {
        int minVal = prices[0];
        int maxProfit = 0;
        for(int i = 1; i < prices.length; i++){
            maxProfit = Math.max(maxProfit,prices[i]-minVal);
            if(prices[i] < minVal){
                minVal = prices[i];
            }
        }
        return maxProfit;
    }
}

实战9 122. 买卖股票的最佳时机 II

class Solution {
    public int maxProfit(int[] prices) {
        // dp[i][0] 不持有股票的收益 , dp[i][1] 只有股票时收益
        int[][] dp = new int[prices.length][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for(int i = 1; i < prices.length ; i++){
            dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
        }
        return dp[prices.length-1][0];
    }
}