leecode更新
This commit is contained in:
parent
607b5f6af2
commit
933ab91051
|
|
@ -96,7 +96,7 @@ public class T27_LengthOfLIS {
|
|||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
d[pos + 1] = nums[i];
|
||||
d[pos + 1] = nums[i];//把第一个小于的位置替换成这个数//并不影响原本的长度,只有后续比他更长了,才会影响他的长度
|
||||
}
|
||||
}
|
||||
return len;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
package com.markilue.leecode.dynamic.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.dynamic.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-02-22 10:35
|
||||
*@Description:
|
||||
* TODO 力扣714题 买卖股票的最佳时机含手续费:
|
||||
* 给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。
|
||||
* 你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
|
||||
* 返回获得利润的最大值。
|
||||
* 注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T26_MaxProfit {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
int[] prices = {1, 3, 2, 8, 4, 9};
|
||||
int fee = 2;
|
||||
System.out.println(maxProfit(prices,fee));
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:仅是每笔交易的时候包含了手续费;在每次买的时候加上手续费即可
|
||||
* 速度击败50.42% 内存击败89.43%
|
||||
* @param prices
|
||||
* @param fee
|
||||
* @return
|
||||
*/
|
||||
public int maxProfit(int[] prices, int fee) {
|
||||
|
||||
int[][] dp = new int[prices.length][2];
|
||||
|
||||
dp[0][0] = 0;
|
||||
dp[0][1] = -prices[0] - fee;
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
|
||||
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]-fee);
|
||||
}
|
||||
|
||||
return dp[dp.length-1][0];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 一维dp优化
|
||||
* 速度击败99.96% 内存击败36.47% 3ms
|
||||
* @param prices
|
||||
* @param fee
|
||||
* @return
|
||||
*/
|
||||
public int maxProfit1(int[] prices, int fee) {
|
||||
|
||||
int dp0 = 0;
|
||||
int dp1 = -prices[0] - fee;
|
||||
int temp;
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
temp=dp0;
|
||||
dp0=Math.max(dp0,dp1+prices[i]);
|
||||
dp1=Math.max(dp1,temp-prices[i]-fee);
|
||||
}
|
||||
|
||||
return dp0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 贪心算法: 核心在于 何时才真正卖出
|
||||
* @param prices
|
||||
* @param fee
|
||||
* @return
|
||||
*/
|
||||
public int maxProfit2(int[] prices, int fee) {
|
||||
|
||||
int buy=prices[0]+fee;
|
||||
int sum=0;
|
||||
|
||||
for (int price : prices) {
|
||||
if(price+fee<buy){//后续如果比8大的数,如果在之前遇到了p + fee<buy的情况,那么后续就一定有正收益了,所以之前的可以放心卖
|
||||
buy=price+fee;//寻找最小价格
|
||||
}else if(price>buy){
|
||||
sum += price - buy;//假装排除计算收益
|
||||
buy = price;//后期如果有数比他大,那么就是计算加上的p-buy增值收益
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.markilue.leecode.dynamic.second;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.dynamic.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-02-22 10:58
|
||||
*@Description:
|
||||
* TODO leecode300 最长递增子序列:
|
||||
* 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
|
||||
* 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T27_LengthOfLIS {
|
||||
|
||||
|
||||
/**
|
||||
* 思路:注意是子序列,可以删除前后元素,找最长 因为可以删除 所以可以将状态分为两种 :要当前的词 不要当前的词 TODO 不知道如何保存状态,未能做出
|
||||
* TODO dp五部曲:
|
||||
* 1.dp定义: dp[i][0]表示不要当前当前的词的最长序列长度 dp[i][1]表示要当前的词的最长序列长度
|
||||
* 2.dp状态转移方程: //因为没法保存状态,所以只能暴力依次比较 时间复杂度O(n^2)
|
||||
* 3.dp初始化:
|
||||
* 4.dp遍历顺序:
|
||||
* 5.dp举例推导:
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int lengthOfLIS(int[] nums) {
|
||||
int[] dp = new int[nums.length];
|
||||
Arrays.fill(dp, 1);
|
||||
int result = 0;
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
for (int j = 0; j < i; j++) {//本质上还是依次比较寻找最大的
|
||||
if (nums[i] > nums[j]) {
|
||||
dp[i] = Math.max(dp[i], dp[j] + 1);
|
||||
}
|
||||
}
|
||||
if (dp[i] > result) result = dp[i]; // 取长的子序列
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.markilue.leecode.dynamic.second;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.dynamic.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-02-22 11:47
|
||||
*@Description:
|
||||
* TODO 力扣674题 最长连续递增序列:
|
||||
* 给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
|
||||
* 连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,
|
||||
* 那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T28_FindLengthOfLCIS {
|
||||
|
||||
/**
|
||||
* 思路:不同之处在于 要连续递增 所以要维护的是一个子数组,由于是连续的,所以比较
|
||||
* TODO DP五部曲;
|
||||
* 1.dp定义:
|
||||
* 2.dp状态转移方程:
|
||||
* 3.dp初始化:
|
||||
* 4.dp遍历顺序:
|
||||
* 5.dp举例推导:
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int findLengthOfLCIS(int[] nums) {
|
||||
|
||||
int maxLength = 1;
|
||||
int curLength = 1;
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
if (nums[i] > nums[i - 1]) {
|
||||
curLength++;
|
||||
} else {
|
||||
curLength = 1;//小于就重置
|
||||
}
|
||||
|
||||
if (curLength > maxLength) maxLength = curLength;
|
||||
}
|
||||
return maxLength;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动态规划法
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int findLengthOfLCIS1(int[] nums) {
|
||||
int nowLength=1;
|
||||
int[] dp = new int[nums.length];
|
||||
dp[0]=1;
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
if (nums[i] > nums[i-1]) {
|
||||
nowLength+=1;//状态递推
|
||||
}else {
|
||||
nowLength=1;
|
||||
}
|
||||
dp[i]=Math.max(dp[i-1],nowLength);
|
||||
}
|
||||
return dp[nums.length-1];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.markilue.leecode.dynamic.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.dynamic.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-02-22 11:56
|
||||
*@Description:
|
||||
* TODO 力扣718题 最长重复子数组:
|
||||
* 给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T29_FindLength {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums1 = {0, 1, 1, 1, 1};
|
||||
int[] nums2 = {1, 0, 1, 0, 1};
|
||||
System.out.println(findLength(nums1, nums2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:
|
||||
* TODO DP五部曲:
|
||||
* 1.dp定义:dp[i][j]表示 使用nums1[0-i]和nums2[0-j]所返回的最长长度
|
||||
* 2.dp状态转移方程:
|
||||
* dp[i][j] 可以是 不要nums2[j] 不要nums1[i] 或者nums[i]==nums[j]
|
||||
* dp[i][j] if(nums[i-1]!=nums[j-1]) max(dp[i-1][j],dp[i][j-1])
|
||||
* else dp[i-1][j-1]+1
|
||||
* 3.dp初始化:为了初始化方便,取nums[i-1]!=nums[j-1]的关系 dp[i][0]=0; dp[0][j]=0;
|
||||
* 4.dp遍历顺序:
|
||||
* 5.dp举例推导:
|
||||
* @param nums1
|
||||
* @param nums2
|
||||
* @return
|
||||
*/
|
||||
public int findLength(int[] nums1, int[] nums2) {
|
||||
|
||||
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
|
||||
int result = 0;
|
||||
|
||||
for (int i = 1; i < dp.length; i++) {
|
||||
for (int j = 1; j < dp[0].length; j++) {
|
||||
if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
|
||||
//因为是子数组,不是子序列,所以一不想等,就直接等于0了,不做处理
|
||||
if (result < dp[i][j]) result = dp[i][j];
|
||||
// else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 一维dp优化
|
||||
* @param nums1
|
||||
* @param nums2
|
||||
* @return
|
||||
*/
|
||||
public int findLength1(int[] nums1, int[] nums2) {
|
||||
|
||||
int[] dp = new int[nums2.length + 1];
|
||||
int result = 0;
|
||||
|
||||
for (int i = 1; i < nums1.length + 1; i++) {
|
||||
for (int j = dp.length - 1; j >= 1; j--) {
|
||||
//返许遍历,因为dp[j]要用到dp[i-1]
|
||||
if (nums1[i - 1] == nums2[j - 1]) {
|
||||
dp[j] = dp[j - 1] + 1;
|
||||
}else {
|
||||
dp[j]=0; //TODO 特别需要注意: 如果不等需要重新赋值,避免不覆盖的情况;而二维的时候不用,因为不用重复利用
|
||||
}
|
||||
//因为是子数组,不是子序列,所以一不想等,就直接等于0了,不做处理
|
||||
if (result < dp[j]) result = dp[j];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue