343. Integer Break (Medim)
题目描述
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
思路
当i≥2 时,假设对正整数 i 拆分出的第一个正整数是 j(1≤j将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j×(i−j);
将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j×dp[i−j]。
class Solution {public int integerBreak(int n) {int[] dp = new int[n+1];dp[1] = 1;dp[2] = 1;for(int i=3; i<=n; i++){for(int j = 2; j<i; j++){dp[i] =Math.max( Math.max(j*(i-j),j*dp[i-j]), dp[i]);}}return dp[n];}}
其他优化见leetcode题解
279. Perfect Squares(Medium)
题目描述
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
思路
同上,双重循环遍历
class Solution {public int numSquares(int n) {List<Integer> list = new ArrayList<>();for(int i=1; i<=n/2; i++){list.add(i*i);}int[] dp = new int[n+1];dp[1] = 1;for(int i=2; i<n+1; i++){int min = Integer.MAX_VALUE;for(int sq: list){if(sq>i){break;}min = Math.min(min,dp[i-sq]+1);}dp[i] = min;}return dp[n];}}
91. Decode Ways (Medium)
题目描述
一条包含字母 A-Z 的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
题目数据保证答案肯定是一个 32 位的整数。
示例
输入:s = “226”
输出:3
解释:它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6) 。
思路
若c[i]与c[i-1]构成的数小于等于26,dp[i] = dp[i-1] + dp[i-2], 否则,dp[i]=dp[i-1]. 零需要单独考虑!
class Solution {public int numDecodings(String s) {int len = s.length();int[] dp = new int[len+1];dp[0] = 1;dp[1] = s.charAt(0)=='0'?0:1;int pre = s.charAt(0) - '0';for(int i=2; i<len+1; i++){int cur = s.charAt(i-1)-'0';if(cur!=0){dp[i] = dp[i]+dp[i-1];}if(pre==0){pre = cur;continue;}if(pre*10+cur<=26){dp[i] += dp[i-2];}pre = cur;}return dp[len];}}
结果 
