动态规划

73 阅读1分钟

零钱兑换

leetcode.cn/problems/co…

class Solution {
    public int coinChange(int[] coins, int amount) {
        /**
         * 定义dp为每个凑到每个数额需要最少的硬币数
         * 初始化时定义dp中每个数都是amout+1,可以让最后判断是否能凑齐amout
         * **/
        int n = amount + 1;
        int[] dp = new int[n];
        Arrays.fill(dp, n);
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            for (int j = 0; j < coins.length; j++) {
                if (i >= coins[j]) {
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
}

最长递增子序列

leetcode.cn/problems/lo…

class Solution {
    public int lengthOfLIS(int[] nums) {
        /**
         * dp表示到每个数字为止的最长严格递增子序列
         * 
         * **/
        int len = nums.length;
        if (len == 0) return 0;
        if (len == 1) return 1;
        int[] dp = new int[len];
        Arrays.fill(dp, 1);
        int max = -1;
        dp[0] = 1;
        for (int i = 1; i < len; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            if (dp[i] > max) {
                max = dp[i];
            }
        }
        return max;
    }
}

连续子数组的最大和

leetcode.cn/problems/li…

class Solution {
    /**
     * dp代表到没给数字为止的最大和,如果后一个数字比前一个数字大,把它本身和前面的最大和相加否则最大和等于他自己。
     * 
     * **/
    public int maxSubArray(int[] nums) {
        int len = nums.length;
        int[] dp = new int[len];
        dp[0] = nums[0];
        int max = dp[0];
        for (int i = 1; i < len; i++) {
            dp[i] = dp[i - 1] + nums[i] > nums[i] ? dp[i - 1] + nums[i] : nums[i];
            if (dp[i] > max) {
                max = dp[i];
            }
        }
        return max;
    }
}

最长回文子串

leetcode.cn/problems/lo…

class Solution {
    /**
     * 中心扩散,以每个点为中心,开始扩散,然后拿到长度与最大长度比较
     * **/
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) {
            return "";
        }
        int maxleft = 0;
        int maxright = 0;
        int maxlen = 0;
        int len = 1;
        for (int mid = 0; mid < s.length(); mid++) {
            int left = mid - 1;
            int right = mid + 1;
            while (left >= 0 && s.charAt(left) == s.charAt(mid)) {
                left--;
                len++;
            }
            while (right < s.length() - 1 && s.charAt(mid) == s.charAt(right)) {
                right++;
                len++;
            }
            while (left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
                right++;
                left--;
                len += 2;
            }
            if (len > maxlen) {
                maxleft = left;
                maxright = right;
                maxlen = len;
            }
            len = 1;
        }
        return s.substring(maxleft + 1, maxright);
    }
}
class Solution {
    /**
     * dp代表,i到j的位置是不是回文串
     * **/
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 2) {
            return s;
        }
        int strLen = s.length();
        int maxStart = 0;  //最长回文串的起点
        int maxEnd = 0;    //最长回文串的终点
        int maxLen = 1;  //最长回文串的长度

        boolean[][] dp = new boolean[strLen][strLen];

        for (int r = 1; r < strLen; r++) {
            for (int l = 0; l < r; l++) {
                if (s.charAt(l) == s.charAt(r) && (r - l <= 2 || dp[l + 1][r - 1])) {
                    dp[l][r] = true;
                    if (r - l + 1 > maxLen) {
                        maxLen = r - l + 1;
                        maxStart = l;
                        maxEnd = r;

                    }
                }

            }

        }
        return s.substring(maxStart, maxEnd + 1);
    }
}