思路:
确定dp:dp[i][j]子串是否是回文串
确定递推公式:
例如:aa|cbc|aa dp[2][4] = dp[3][3] true
确定初始化:dp[i][i] = true,一个字母都是回文
确定遍历顺序:子串从长度2开始一直到len长度,从小到大。i从小到大,不可以更换顺序
两个一组从头遍历到尾,三个一组从头遍历到尾,456....len个一组遍历到尾
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2) {
return s;
}
int maxLen = 1;
int begin = 0;
// dp[i][j] 表示 s[i..j] 是否是回文串
boolean[][] dp = new boolean[len][len];
// 初始化:所有长度为 1 的子串都是回文串
for (int i = 0; i < len; i++) {
dp[i][i] = true;
}
for(int l = 2;l<=len;l++){
for(int i = 0;i=len){
break;
}
dp[i][j] = false;
if(s.charAt(i) == s.charAt(j)){
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
if(dp[i][j]&&j-i+1>maxLen){
maxLen = j-i+1;
begin = i;
}
}
}
}
return s.substring(begin, begin + maxLen);
}
}
思路:
确定dp:dp[i][j]子串是否是回文串(上一问方法),f[i]第i个字符最少的分割次数
确定递推公式:
确定初始化:f[i] = Integer.MAX_VALUE
确定遍历顺序:从前往后
class Solution {
public int minCut(String s) {
int len = s.length();
boolean[][] dp = new boolean[len][len];
for(int i = 0;i=len){
break;
}
dp[i][j] = false;
if(s.charAt(i) == s.charAt(j)){
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}
}
}
//分割次数
int[] f = new int[len];
for(int i = 0;i
思路:
确定dp:dp[i][j] text1前i个字符和text2前j个字符最长公共子序列
确定递推公式:
确定初始化:默认都是0
确定遍历顺序:从前往后
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];
char[] s1 = text1.toCharArray();
char[] s2 = text2.toCharArray();
for(int i = 0;i
思路:
p[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。
相等不相等两种情况:
if (word1[i - 1] == word2[j - 1])
那么就不用编辑,dp[i][j] = dp[i - 1][j - 1];
if (word1[i - 1] != word2[j - 1])
class Solution {
public int minDistance(String word1, String word2) {
char[] s1 = word1.toCharArray();
char[] s2 = word2.toCharArray();
int len1 = s1.length;
int len2 = s2.length;
int[][] dp = new int[len1+1][len2+1];
for(int i = 0;i<=len1;i++){
dp[i][0] = i;
}
for(int i = 0;i<=len2;i++){
dp[0][i] = i;
}
for(int i = 0;i
思路:
确定dp:dp[i][j] s前i个字符和p前j个字符是否能匹配
确定递推公式:
确定初始化:dp[0][0]=true 空串匹配
确定遍历顺序:从前往后
class Solution {
public boolean isMatch(String s, String p) {
int lens = s.length();
int lenp = p.length();
char[] sc = s.toCharArray();
char[] pc = p.toCharArray();
boolean[][] dp = new boolean[lens+1][lenp+1];
dp[0][0] = true;
for(int i = 0;i<=lens;i++){
for(int j = 1;j<=lenp;j++){
//从1开始防止越界
if(i>0&&(pc[j-1] == '.'||pc[j-1] == sc[i-1])){
dp[i][j] = dp[i-1][j-1];
}else if(pc[j-1] == '*'){
if(i>0&&(pc[j-2] == sc[i-1]||pc[j-2] == '.')){
//匹配0/1、多个,需要加上匹配0个,a ..* .*丢弃
dp[i][j]=dp[i][j-1]|dp[i-1][j]|dp[i][j-2];
}else{
dp[i][j] = dp[i][j-2];
}
}
}
}
return dp[lens][lenp];
}
}
思路:
确定dp:
dp[i]第i个字符最大乘积dp[i]=max(dp[i-1]*nums[i],nums[i]),这样忽略了负负得正的情况
max[i]当前子数组对应的最大乘积
min[i]当前子数组对应的最小乘积
确定递推公式:
三种情况取最大和最小
max[i] = Math.max(max[i-1]*nums[i],Math.max(min[i-1]*nums[i],nums[i]));
确定初始化:
确定遍历顺序:从前往后
class Solution {
public int maxProduct(int[] nums) {
int[] max = new int[nums.length];
int[] min = new int[nums.length];
max[0] = nums[0];
min[0] = nums[0];
int res = nums[0];
for(int i = 1;ires){
res = max[i];
}
}
return res;
}
}
思路:prices[i] - min就是最大差价
class Solution {
public int maxProfit(int[] prices) {
int min = prices[0];
int gap = 0;
int res = 0;
for(int i = 1;i
思路:
确定dp:
dp[i][0]不持有当前股票所有资金
dp[i][1]持有当前股票所有资金
确定递推公式:
确定初始化:dp[0][0]=0 dp[0][1] = -prices[0]当天买入
确定遍历顺序:从前往后
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i = 1;i
思路:
确定dp:
dp[i][0][1]不持有当前股票所有资金,并且处于或者已完成第一次交易
dp[i][1][2]持有当前股票所有资金,并且处于或者已经完成第二次交易
确定递推公式:
确定初始化:dp[0][1][1]=-prices[0] dp[0][1][2] = -prices[0]持有状态说明买入
确定遍历顺序:从前往后
class Solution {
public int maxProfit(int[] prices) {
int[][][] dp = new int[prices.length][2][3];
dp[0][0][0] = 0;
dp[0][1][1] = -prices[0];
dp[0][1][2] = -prices[0];
for(int i = 1;i
思路:
确定dp:dp[i]到当前房屋所能获得的最大金额
确定递推公式:dp[i] = Math.max(dp[i-1],dp[i-2] + nums[i]);偷当前房屋和不偷当前房屋
确定初始化:dp[0] = nums[0] dp[1] = max(nums[0],nums[1])
确定遍历顺序:从前往后
class Solution {
public int rob(int[] nums) {
if(nums.length == 1){
return nums[0];
}
if(nums.length == 0){
return 0;
}
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0],nums[1]);
for(int i = 2;i