1. 爬楼梯
class Solution {
public int climbStairs(int n) {
if (n < 3) {
return n;
}
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
2. 斐波那契数
class Solution {
public int fib(int n) {
if (n < 2) {
return n;
}
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
3. 解码方法(常考题)
class Solution {
public int numDecodings(String s) {
int n = s.length();
if (n == 0) {
return 0;
}
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;
for (int i = 2; i <= n; i++) {
int twoDigit = Integer.valueOf(s.substring(i - 2, i));
int oneDigit = Integer.valueOf(s.substring(i - 1, i));
if (10 <= twoDigit && twoDigit <= 26) {
dp[i] += dp[i - 2];
}
if (oneDigit != 0) {
dp[i] += dp[i - 1];
}
}
return dp[n];
}
}
4. 单词拆分
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] dp = new boolean[n + 1];
dp[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordDict.contains(s.substring(j, i))) {
dp[i] = true;
}
}
}
return dp[n];
}
}
5. 单词拆分 II
class Solution {
public List<String> wordBreak(String s, List<String> wordDict) {
int n = s.length();
List<String> res = new ArrayList<>();
List<Integer>[] dp = new ArrayList[n + 1];
for (int i = 0; i <= n; i++) {
dp[i] = new ArrayList<>();
}
dp[0].add(0);
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
if (!dp[j].isEmpty() && wordDict.contains(s.substring(j, i))) {
dp[i].add(j);
}
}
}
dfs(s, res, n, dp, "");
return res;
}
private void dfs(String s, List<String> res, int index, List<Integer>[] dp, String cur) {
if (index == 0) {
res.add(cur.trim());
return;
}
for (Integer j : dp[index]) {
dfs(s, res, j, dp, s.substring(j, index) + " " + cur);
}
}
}
6. 最大子数组和
class Solution {
public int maxSubArray(int[] nums) {
int cur = 0;
int max = Integer.MIN_VALUE;
int n = nums.length;
for (int i = 0; i < n; i++) {
max = Math.max(cur + nums[i], max);
if (nums[i] + cur > 0) {
cur = cur + nums[i];
} else {
cur = 0;
}
}
return max;
}
public int maxSubArray(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < n; i++) {
dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
max = Math.max(max, dp[i]);
}
return max;
}
}
7. 乘积最大子数组
class Solution {
public int maxProduct(int[] nums) {
int n = nums.length;
int[] min = new int[n];
int[] max = new int[n];
min[0] = nums[0];
max[0] = nums[0];
int res = nums[0];
for (int i = 1; i < n; i++) {
if (nums[i] > 0) {
max[i] = Math.max(nums[i], max[i - 1] * nums[i]);
min[i] = Math.min(nums[i], min[i - 1] * nums[i]);
} else {
max[i] = Math.max(nums[i], min[i - 1] * nums[i]);
min[i] = Math.min(nums[i], max[i - 1] * nums[i]);
}
res = Math.max(res, max[i]);
}
return res;
}
}
8. 最长递增子序列
class Solution {
public int lengthOfLIS1(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp, 1);
int max = dp[0];
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
max = Math.max(max, dp[i]);
}
return max;
}
}