动态规划篇

最长回文子字符串

中心扩散法

class Solution {
    public String longestPalindrome(String s) {
        int max=0;int maxleft=0;int maxright=0;int sum=0;
        for(int i=0;i<s.length();i++){
            int left=i;int right=i;
            //向左寻找到第一个不与i相等的数
            while(left>=0&&s.charAt(left)==s.charAt(i)){
                sum=i-left+1;
                if(max<sum){
                    max=Math.max(sum,max);
                    maxleft=left;
                    maxright=i;
                }
                left--;
            }
            //向右寻找到第一个不与i相等的数
            while(right<=s.length()-1&&s.charAt(right)==s.charAt(i)){
                sum=right-i+1;
                if(max<sum){
                    max=Math.max(sum,max);
                    maxleft=i;
                    maxright=right;
                }
                right++;
            }
            //向两边扩散
            while(left>=0&&right<=s.length()-1&&s.charAt(left)==s.charAt(right)){
                sum=right-left+1;
                if(max<sum){
                    max=Math.max(sum,max);
                    maxleft=left;
                    maxright=right;
                }
                left--;
                right++;
            }
        }
        return s.substring(maxleft,maxright+1);
    }
}

动态规划

class Solution {
    public String longestPalindrome(String s) {
        int dp[][]=new int[s.length()][s.length()];//i,j范围内是否是回文子串
        dp[s.length()-1][s.length()-1]=1;
        int max=0;int l=0;int r=0;
        for(int i=0;i<s.length();i++){
            dp[i][i]=1;
        }
        for(int i=s.length()-2;i>=0;i--){
            for(int j=i+1;j<s.length();j++){
                if(s.charAt(i)==s.charAt(j)&&(dp[i+1][j-1]!=0||j-i==1)){
                    
                    dp[i][j]=dp[i+1][j-1]+2;
                    
                }
                if(max<dp[i][j]){
                    l=i;r=j;
                }
                max=Math.max(max,dp[i][j]);
            }
        }
        return s.substring(l,r+1);
    }
}

最长递增子序列(不一定连续)

class Solution {
    public int lengthOfLIS(int[] nums) {
        int dp[]=new int[nums.length];//0-i的递增子序列长度
        Arrays.fill(dp,1);
        int max=dp[0];

        for(int i=1;i<nums.length;i++){
            for(int j=0;j<i;j++){
                if(nums[i]>nums[j]){
                    dp[i]=Math.max(dp[i],dp[j]+1);
                }
            }
            System.out.println("i="+i);
            System.out.println("dp[i]="+dp[i]);
            max=Math.max(max,dp[i]);
        }
        return max;
    }
}

编辑距离

class Solution {
    public int minDistance(String word1, String word2) {
        //dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]
        //dp[i][0] :以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]
        int m = word1.length();
        int n = word2.length();
        int[][] dp = new int[m + 1][n + 1];
        // 初始化
        for (int i = 1; i <= m; i++) {
            dp[i][0] =  i;
        }
        for (int j = 1; j <= n; j++) {
            dp[0][j] = j;
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                // 因为dp数组有效位从1开始
                // 所以当前遍历到的字符串的位置为i-1 | j-1
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
                }
            }
        }
        return dp[m][n];
    }
}

零钱兑换

 

class Solution {
    public int coinChange(int[] coins, int amount) {
        if(coins.length == 0)
            return -1;
    	//dp[j]代表当钱包的总价值为j时,所需要的最少硬币的个数
    	int[] dp = new int[amount+1];
    	Arrays.fill(dp,amount+1);
    	dp[0]=0;
    	for(int i = 1;i<=amount;i++) {
		    for (int j = 0;j<coins.length;j++) {
                if(coins[j]<=i)
                    dp[i] = Math.min(dp[i], dp[i-coins[j]]+1);
            }
		}
        if(dp[amount] !=amount+1)
    		return dp[amount];
    	return -1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值