标题
- 碎碎念
- 模板
- 10 正则表达式匹配 (Regular Expression Matching)
- 53 最大子序和 (Maximum Subarray)
- 55 跳跃游戏 (Jump Game)
- 62 不同路径 (Unique Paths)
- 63 不同路径 II (Unique Paths II)
- 64 Minimum Path Sum
- 70 Climbing Stairs
- 91 Decode Ways
- 97 Interleaving String
- 120 Triangle
- 121 Best Time To Buy And Sell Stock
- 122 Best Time To Buy And Sell Stock II
- 152 Maximum Product Subarray
- 198 House Robber
- 213 House Robber II
- 300 Longest Increasing Subsequence
- 312 Burst Balloons
- 322 Coin Change
- 337 House Robber III
- 354 Russian Doll Envelopes
- 416 Partition Equal Subset Sum
- 516 Longest Palindromic Subsequence
- 887 Super Egg Drop (待优化)
- 518 Coin Change 2
- 1312 Minimum Insertion Steps To Make A String Palindrome
- Offer 20 回文子字符串的个数(待优化)
碎碎念
之前把所有写的力扣题放在一个连接里,真的太傻了,现在写起来很卡,所以现在开个转栏放各个类型。文章会慢慢搬过来的。之前的文章在这:
https://blog.csdn.net/weixin_51766963/article/details/120135022
模板
//动态规划
public void dynamicProgramming(int[] num, int target) {
int[] dp = new int[num.length];
//状态一
for (int i = 0; i < num.length; i++) {
//状态二
for (int j = 0; j < ; j++) {
//...for状态n
//状态转移方程
//条件判断
dp[状态1][状态2]...=最值(选择1,选择2)
}
}
}
10 正则表达式匹配 (Regular Expression Matching)
https://leetcode-cn.com/problems/regular-expression-matching/
private Map<String, Boolean> memo = new HashMap<>();
public boolean isMatch(String s, String p) {
return dp(s, 0, p, 0);
}
private boolean dp(String s, int i, String p, int j) {
if (i == s.length()) {
if ((p.length() - j) % 2 == 1) {
return false;
}
for (; j + 1 < p.length(); j += 2) {
if (p.charAt(j + 1) != '*') {
return false;
}
}
return true;
}
if (j == p.length()) {
return i == s.length();
}
char[] charS = s.toCharArray();
char[] charP = p.toCharArray();
String key = i + "," + j;
if (memo.containsKey(key)) return memo.get(key);
boolean res;
if (charS[i] == charP[j] || charP[j] == '.') {
if (j + 1 < p.length() && charP[j + 1] == '*') {
res = dp(s, i, p, j + 2) || dp(s, i + 1, p, j);
} else {
res = dp(s, i + 1, p, j + 1);
}
} else {
if (j + 1 < p.length() && charP[j + 1] == '*') {
res = dp(s, i, p, j + 2);
} else {
res = false;
}
}
memo.put(key, res);
return res;
}
53 最大子序和 (Maximum Subarray)
public int maxSubArray(int[] nums) {
if (nums.length == 0) return 0;
int[] dp = new int[nums.length];
dp[0] = nums[0];
int res = Integer.MIN_VALUE;
for (int i = 1; i < nums.length; i++) {
if (dp[i - 1] > 0) {
dp[i] = dp[i - 1] + nums[i];
} else {
dp[i] = nums[i];
}
res = Math.max(res, dp[i]);
}
return res;
}
//优化一下,可以不需要dp数组
public int maxSubArray2(int[] nums) {
if (nums.length == 0) return 0;
int dpNum = nums[0];
int res = dpNum;
for (int i = 1; i < nums.length; i++) {
if (dpNum > 0) {
dpNum += nums[i];
} else {
dpNum = nums[i];
}
res = Math.max(res, dpNum);
}
return res;
}
55 跳跃游戏 (Jump Game)
https://leetcode-cn.com/problems/jump-game/
public boolean canJump(int[] nums) {
if(nums==null)return true;
if(nums[0]==0&&nums.length>1)return false;
boolean flag=false;
for(int i = nums.length-2;i>0;i--){
if(nums[i]==0){
flag=false;
int step=0;
while(i>0){
step++;
i--;
if(nums[i]>step){
flag=true;
break;
}
}
if(!flag)return false;
}
}
return true;
}
62 不同路径 (Unique Paths)
https://leetcode-cn.com/problems/unique-paths/
62、63、64 都属于同一种类型的,可以一起做一下
public int uniquePaths(int m, int n) {
int dp[][]=new int [m][n];
for(int i =0;i<m;i++){
dp[i][0]=1;
}
for(int i =0;i<n;i++){
dp[0][i]=1;
}
for(int i =1;i<m;i++){
for(int j =1;j<n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
63 不同路径 II (Unique Paths II)
https://leetcode-cn.com/problems/unique-paths-ii/
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if(obstacleGrid==null)return 0;
int row =obstacleGrid.length;
int column =obstacleGrid[0].length;
int[][]dp = new int[row][column];
if(obstacleGrid[0][0]==1)return 0;
dp[0][0]=1;
for(int i =1;i<row;i++){
if(obstacleGrid[i][0]!=1)dp[i][0]=dp[i-1][0];
}
for(int i =1;i<column;i++){
if(obstacleGrid[0][i]!=1)dp[0][i]=dp[0][i-1];
}
for(int i =1;i<row;i++){
for(int j =1;j<column;j++){
if(obstacleGrid[i][j]!=1)dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[row-1][column-1];
}
64 Minimum Path Sum
https://leetcode-cn.com/problems/minimum-path-sum/
public int minPathSum(int[][] grid) {
if(grid==null)return 0;
int row=grid.length;
int column=grid[0].length;
for(int i =1;i<row;i++){
grid[i][0]+=grid[i-1][0];
}
for(int i =1;i<column;i++){
grid[0][i]+=grid[0][i-1];
}
for(int i =1;i<row;i++){
for(int j =1;j<column;j++){
grid[i][j]+=Math.min(grid[i-1][j],grid[i][j-1]);
}
}
return grid[row-1][column-1];
}
70 Climbing Stairs
https://leetcode-cn.com/problems/climbing-stairs/
public int climbStairs(int n){
if(n==0)return 0;
if(n==1)return 1;
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];
}
91 Decode Ways
https://leetcode-cn.com/problems/decode-ways/
public int numDecodings(String s) {
int length = s.length();
int[] dp = new int[length + 1];
dp[0]=1;
for (int i = 1; i <= length; i++) {
if(s.charAt(i-1)!='0'){
dp[i]+=dp[i-1];
}
if(i>1&&s.charAt(i-2)!='0'&&((s.charAt(i-2)-'0')*10+(s.charAt(i-1)-'0'))<=26){
dp[i]+=dp[i-2];
}
}
return dp[length];
}
97 Interleaving String
https://leetcode-cn.com/problems/interleaving-string/
public boolean isInterleave(String s1, String s2, String s3) {
//不能这么判断
// if (s1.equals("")) return s2.equals(s3);
// if (s2.equals("")) return s1.equals(s3);
int n = s1.length(), m = s2.length(), t = s3.length();
if (n + m != t) {
return false;
}
boolean[][] dp = new boolean[n + 1][m + 1];
dp[0][0] = true;
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= m; ++j) {
int p = i + j - 1;
if (i > 0) {
dp[i][j] = dp[i][j] || (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p));
}
if (j > 0) {
dp[i][j] = dp[i][j] || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
}
}
}
return dp[n][m];
}
120 Triangle
https://leetcode-cn.com/problems/triangle/
public int minimumTotal(List<List<Integer>> triangle) {
int[][] dp = new int[triangle.size()][triangle.get(triangle.size() - 1).size()];
int res = Integer.MAX_VALUE;
dp[0][0] = triangle.get(0).get(0);
for (int i = 1; i < triangle.size(); i++) {
for (int i1 = 0; i1 < triangle.get(i).size(); i1++) {
dp[i][i1]=triangle.get(i).get(i1);
if (i1 == triangle.get(i).size() - 1) {
dp[i][i1] += dp[i - 1][i1 - 1]+triangle.get(i).get(i1);
continue;
}
if (i1 == 0) {
dp[i][i1] += (dp[i - 1][i1] + triangle.get(i).get(0));
} else {
dp[i][i1] += Math.min(dp[i - 1][i1], dp[i - 1][i1 - 1]) + triangle.get(i).get(i1);
}
}
}
for (int n = 0; n < dp.length; n++) {
res = Math.min(dp[dp.length - 1][n], res);
}
return res;
}
121 Best Time To Buy And Sell Stock
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
public int maxProfit(int[] prices) {
if (prices.length < 1) {
return 0;
}
int min = prices[0],dpValue=0;
for (int i = 0; i < prices.length; i++) {
if (prices[i] - min > dpValue) {
dpValue=prices[i] - min;
}
if(prices[i]<min){
min=prices[i];
}
}
return dpValue;
}
122 Best Time To Buy And Sell Stock II
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
public int maxProfit(int[] prices) {
if (prices.length<=1)return 0;
int[][] dp = new int[prices.length][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for (int i = 1; i <prices.length ; i++) {
dp[i][0]=Math.max(dp[i-1][1]+prices[i],dp[i-1][0]);
dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
}
return dp[prices.length-1][0];
}
public int maxProfit(int[] prices) {
if (prices.length<=1)return 0;
int res = 0;
for (int i = 1; i <prices.length; i++) {
res+=Math.max(0,prices[i]-prices[i-1]);
}
return res;
}
152 Maximum Product Subarray
https://leetcode-cn.com/problems/maximum-product-subarray/
public int maxProduct(int[] nums) {
if(nums==null)return 0;
int maxP=nums[0];
int minP=nums[0];
int res = nums[0];
for(int i =1;i<nums.length;i++){
int tempMax=maxP,tempMin=minP;
maxP=Math.max(Math.max(nums[i],tempMax*nums[i]),tempMin*nums[i]);
minP=Math.min(Math.min(nums[i],tempMin*nums[i]),tempMax*nums[i]);
res=Math.max(maxP,res);
}
return res;
}
198 House Robber
https://leetcode-cn.com/problems/house-robber/
// public int rob(int[] nums) {
// if(nums==null)return 0;
// if(nums.length==1)return nums[0];
// int dp[]=new int [nums.length];
// dp[0]=nums[0];
// dp[1]=nums[1];
// for(int i =2;i<nums.length;i++){
// int max= 0;
// for(int j=0;j<i-1;j++){
// dp[i]=max=Math.max(dp[j]+nums[i],max);
// }
// }
// int max=0;
// for(int i =0;i<nums.length;i++){
// max=Math.max(max,dp[i]);
// }
// return max;
// }
public int rob(int[] nums) {
if(nums==null)return 0;
if(nums.length==1)return nums[0];
int dp[]=new int[nums.length];
dp[0]=nums[0];
dp[1]=Math.max(nums[0],nums[1]);
for(int i =2;i<nums.length;i++){
dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.length-1];
}
213 House Robber II
https://leetcode-cn.com/problems/house-robber-ii/
public int rob(int[] nums) {
if(nums==null)return 0;
if(nums.length==1)return nums[0];
return Math.max(robArr(nums,0,nums.length-1),robArr(nums,1,nums.length));
}
public int robArr(int [] nums,int start, int end){
int[] a = new int[end-start];
int sTemp=start;
for(int i =0;i<end-start;i++){
a[i]=nums[sTemp];
sTemp++;
}
return rob1(a);
}
public int rob1(int[] nums) {
if(nums==null)return 0;
if(nums.length==1)return nums[0];
int dp[]=new int[nums.length];
dp[0]=nums[0];
dp[1]=Math.max(nums[0],nums[1]);
for(int i =2;i<nums.length;i++){
dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.length-1];
}
300 Longest Increasing Subsequence
https://leetcode-cn.com/problems/longest-increasing-subsequence/
public int lengthOfLIS(int[] nums) {
if (nums.length < 1) return 0;
if (nums.length == 1) return 1;
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
for (int i = 0; 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);
}
}
}
int res = 0;
for (int i = 0; i < nums.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
312 Burst Balloons
https://leetcode-cn.com/problems/burst-balloons/
dp[i][j]:戳破第i个气球和第j个气球之间的所有气球得到的最大分数
public int maxCoins(int[] nums) {
if(nums==null)return 0;
int point[] = new int[nums.length+2];
point[0]=1;
point[nums.length+1]=1;
for (int i = 1; i <=nums.length ;i++) {
point[i]=nums[i-1];
}
int dp[][] = new int[nums.length+2][nums.length+2];
for (int i = point.length-2; i >=0 ; i--) {
for (int j = i+1; j <point.length ; j++) {
for (int k = i+1; k <j ; k++) {
dp[i][j]=Math.max(dp[i][j],dp[i][k]+dp[k][j]+point[i]*point[k]*point[j]);
}
}
}
return dp[0][point.length-1];
}
322 Coin Change
https://leetcode-cn.com/problems/coin-change/
public int coinChange(int[] coins, int amount) {
if (coins.length == 0) return -1;
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 (i >= coins[j]) {
dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
}
}
}
return dp[amount] == amount + 1 ? -1 : dp[amount];
}
337 House Robber III
https://leetcode-cn.com/problems/house-robber-iii/
Map<TreeNode,Integer> map = new HashMap<>();
public int rob(TreeNode root) {
if(root ==null)return 0;
if (map.containsKey(root)) {
return map.get(root);
}
int nextLine = rob(root.left) + rob(root.right);
int left =root.left==null?0:(rob(root.left.left)+rob(root.left.right));
int right =root.right==null?0:(rob(root.right.left)+rob(root.right.right));
int max = Math.max(nextLine, left + right + root.val);
map.put(root,max);
return max;
}
354 Russian Doll Envelopes
https://leetcode-cn.com/problems/russian-doll-envelopes/
public int maxEnvelopes(int[][] envelopes) {
Arrays.sort(envelopes, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if(o1[0]!=o2[0])return o1[0]-o2[0];
if(o1[1]>=o2[1]) return -1;
else return 1;
}
});
int[] ints = new int[envelopes.length];
for (int i = 0; i < envelopes.length; i++) {
ints[i]=envelopes[i][1];
}
return findLengthOfLCIS(ints);
}
private int findLengthOfLCIS(int[] nums) {
if(nums.length<1)return 0;
if(nums.length==1)return 1;
int [] dp = new int[nums.length];
Arrays.fill(dp,1);
for(int i = 0;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);
}
}
}
int res = 0;
for(int i = 0;i<nums.length;i++){
res = Math.max(res,dp[i]);
}
return res;
}
416 Partition Equal Subset Sum
https://leetcode-cn.com/problems/partition-equal-subset-sum/
public boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0) return false;
sum >>= 1;
boolean dp[][] = new boolean[nums.length + 1][sum + 1];
for (int i = 0; i <= nums.length; i++) {
dp[i][0] = true;
}
for (int i = 1; i <= nums.length; i++) {
for (int j = 1; j <= sum; j++) {
if (j - nums[i - 1] < 0) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i-1]];
}
}
}
return dp[nums.length][sum];
}
public static boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0) return false;
sum >>= 1;
boolean dp[] = new boolean[sum + 1];
dp[0] = true;
for (int i = 0; i < nums.length; i++) {
for (int j = sum; j >= 0; j--) {
if (j - nums[i] >= 0) {
dp[j] = dp[j] || dp[j - nums[i]];
}
}
}
return dp[sum];
}
516 Longest Palindromic Subsequence
https://leetcode-cn.com/problems/longest-palindromic-subsequence/
//普通二位dp
public int longestPalindromeSubseq(String s) {
if(s.length()==0)return 0;
char[] chars = s.toCharArray();
int [][]dp = new int[chars.length][chars.length];
for (int i = 0; i < chars.length; i++) {
dp[i][i]=1;
}
for (int i = chars.length-2; i>=0 ; i--) {
for (int j = i+1; j <chars.length ; j++) {
if(chars[i]==chars[j])dp[i][j]=dp[i+1][j-1]+2;
else dp[i][j]=Math.max(dp[i][j-1],dp[i+1][j]);
}
}
return dp[0][chars.length-1];
}
//普通一维dp
public int longestPalindromeSubseq2(String s) {
if(s.length()==0)return 0;
char[] chars = s.toCharArray();
int []dp = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
dp[i]=1;
}
for (int i = chars.length-2; i>=0 ; i--) {
int pre=0;
for (int j = i+1; j <chars.length ; j++) {
int temp = dp[j];
if(chars[i]==chars[j])dp[j]=pre+2;
else dp[j]=Math.max(dp[j-1],dp[j]);
pre =temp;
}
}
return dp[chars.length-1];
}
887 Super Egg Drop (待优化)
https://leetcode-cn.com/problems/super-egg-drop/
// 不能ac
Map<String,Integer>memo = new HashMap<>();
public int superEggDrop(int k, int n) {
return dp(k,n);
}
private int dp(int k, int n) {
if(k==1)return n;
if(n==0)return 0;
if(memo.containsKey(k+","+n))return memo.get(k+","+n);
int res = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
res=Math.min(res,Math.max(dp(k-1,i-1),dp(k,n-i))+1);
}
memo.put(k+","+n,res);
return res;
}
//二分搜索减枝
Map<String,Integer>memo = new HashMap<>();
public int superEggDrop(int k, int n) {
return dp(k,n);
}
private int dp(int k, int n) {
if(k==1)return n;
if(n==0)return 0;
if(memo.containsKey(k+","+n))return memo.get(k+","+n);
int res = Integer.MAX_VALUE;
int lo=1;
int high=n;
while(lo<=high){
int mid=(lo+high)>>1;
int broken = dp(k-1,mid-1);
int unBroken = dp(k,n-mid);
if(broken>unBroken){
high=mid-1;
res=Math.min(res,broken+1);
}else{
lo=mid+1;
res=Math.min(res,unBroken+1);
}
}
memo.put(k+","+n,res);
return res;
}
518 Coin Change 2
https://leetcode-cn.com/problems/coin-change-2/
public int change(int amount, int[] coins) {
int dp [][] = new int[coins.length+1][amount+1];
for (int i = 0; i <= coins.length; i++) {
dp[i][0]=1;
}
for (int i = 1; i <=coins.length ; i++) {
for (int j = 1; j <=amount ; j++) {
if(j-coins[i-1]>=0){
dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]];
}else {
dp[i][j]=dp[i-1][j];
}
}
}
return dp[coins.length][amount];
}
public int change(int amount, int[] coins) {
int dp[] = new int[amount+1];
dp[0]=1;
for (int i = 1; i <=coins.length ; i++) {
for (int j = 1; j <=amount ; j++) {
if(j-coins[i-1]>=0){
dp[j]=dp[j]+dp[j-coins[i-1]];
}
}
}
return dp[amount];
}
1312 Minimum Insertion Steps To Make A String Palindrome
https://leetcode-cn.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/
public int minInsertions(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] chars = s.toCharArray();
int[] dp = new int[chars.length];
for (int i = dp.length - 2; i >= 0; i--) {
int pre =0;
for (int j = i + 1; j < chars.length; j++) {
int temp=dp[j];
if (chars[i] == chars[j]) dp[j] = pre;
else {
dp[j]=Math.min(dp[j],dp[j-1])+1;
}
pre =temp;
}
}
return dp[chars.length-1];
}
Offer 20 回文子字符串的个数(待优化)
https://leetcode-cn.com/problems/a7VOhD/
//待优化
public int countSubstrings(String s) {
if (s == null || s.length() == 0) return 0;
char[] chars = s.toCharArray();
int[] dp = new int[chars.length];
int j = 0;
for (int i = 0; i < chars.length; i++) {
dp[i] = 1;
}
int count = chars.length;
for (int i = chars.length - 2; i >= 0; i--) {
int pre = 0;
for (j = i + 1; j < chars.length; j++) {
int temp = dp[j];
if (j - i == 1 && chars[i] == chars[j]) {
dp[j] = 1;
count += 1;
} else if (chars[i] == chars[j] && pre >= 1) {
dp[j] = 1;
count += 1;
}else {
dp[j]=0;
}
pre = temp;
}
}
return count;
}