leetcode121
某一天买入股票,未来任意一天卖出,只卖一次,求最大利润
思路:双指针i和j,当i所对应的股票的值小于j所对应的股票的值时记下price[j]-price[i]等于盈利的钱,然后j++,再次比较二者,盈利的钱需要和上次盈利的钱比较保证记录下来的盈利是最大的。如果i所对应的股票的值大于j所对应的股票的值,则说明出现亏损,需要将i变成j,再j++。
完整代码如下:
class Solution {
public int maxProfit(int[] prices) {
int i=0;
int j=1;
int max=0;
while (j<prices.length){
if(prices[j]-prices[i]>0){
max=Math.max(max,prices[j]-prices[i]);
j++;
}else {
i=j;
j++;
}
}
return max;
}
}
leetcode122
某一天买入股票,未来任意一天卖出,只能卖了再买,但可以买卖多次,并允许同一天卖出后再买入,求最大利润
思路:贪心算法,只要买入的价格比卖出的底即有收益就卖,卖完就买。i和j的距离始终是1。
完整代码如下:
class Solution {
public int maxProfit(int[] prices) {
int i=0;
int j=1;
int sum=0;
while (j<prices.length){
if(prices[j]-prices[i]>0){
sum=sum+(prices[j]-prices[i]);
}
i++;
j++;
}
return sum;
}
}
leetcode714
某一天买入股票,未来任意一天卖出,只能卖了再买,但可以买卖多次,不允许同一天卖出后再买入,每笔交易有手续费,求最大利润
思路:动态规划,如果按照上一题的思路,只要有利润就卖,那么可能导致多次的手续费。准备两个数组,一个是买数组,一个是卖数组。
完整代码如下:
//没有降维
class Solution {
public int maxProfit(int[] prices, int fee) {
int [] buy=new int[prices.length];
int [] sell=new int[prices.length];
buy[0]=-prices[0];
sell[0]=0;
for (int i = 1; i < prices.length; i++) {
buy[i]=Math.max(buy[i-1], sell[i-1]-prices[i]);
sell[i]=Math.max(sell[i-1], buy[i-1]+prices[i]-fee);
}
return sell[prices.length-1];
}
}
//降维
class Solution {
public int maxProfit(int[] prices, int fee) {
int buy;
int sell;
buy=-prices[0];
sell=0;
for (int i = 1; i < prices.length; i++) {
buy=Math.max(buy, sell-prices[i]);
sell=Math.max(sell, buy+prices[i]-fee);
}
return sell;
}
}
leetcode309
某一天买入股票,未来任意一天卖出,可以买卖多次,卖出后只能隔天再买入,求最大利润
第一天买和卖还有第二天的买需要特别处理,因为第二天的买需要由前面天的卖剩下的利润决定,但是目前才第二天所以没有前两天的卖,因此默认剩下的利润就是0。
完整代码如下:
class Solution {
public int maxProfit(int[] prices) {
if(prices.length==1)return 0;
int [] buy=new int[prices.length];
int [] sell=new int[prices.length];
buy[0]=-prices[0];
sell[0]=0;
buy[1]=Math.max(-prices[0],-prices[1]);
sell[1]=Math.max(sell[0],buy[0]+prices[1]);
for (int i = 2; i < prices.length; i++) {
buy[i]=Math.max(buy[i-1], sell[i-2]-prices[i]);
sell[i]=Math.max(sell[i-1], buy[i-1]+prices[i]);
}
return sell[prices.length-1];
}
}
leetcode123
某一天买入股票,未来任意一天卖出,只能先卖再买,最多买卖两次,求最大利润
两次就用两对buy和sell,第一对用来记录第一次买卖的,第二对用来记录第二次买卖的。需要注意由于第二天不可产生第二次卖故第二次买卖在第二天的记录和第一次买卖是一样的。
完整代码如下:
class Solution {
public int maxProfit(int k, int[] prices) {
int buy1 = Integer.MIN_VALUE;
int buy2 = Integer.MIN_VALUE;
int sell1 = 0;
int sell2 = 0;
for (int price : prices) {
buy1 = Math.max(buy1, -price);
sell1 = Math.max(sell1, buy1 + price);
buy2 = Math.max(buy2, sell1 - price);
sell2 = Math.max(sell2, buy2 + price);
}
return sell2;
}
}
leetcode188
某一天买入股票,未来任意一天卖出,只能先卖再买,最多买卖K次,求最大利润
两次是用两对,k次就用k对,那么我们就使用buy数组和sell数组长度为k。
完整代码如下:
class Solution {
public int maxProfit(int k, int[] prices) {
int []buy = new int[k];
int []sell = new int[k];
Arrays.fill(buy,Integer.MIN_VALUE);
for (int price : prices) {
buy[0] = Math.max(buy[0], -price);
sell[0] = Math.max(sell[0], buy[0] + price);
for (int i = 1; i < k; i++) {
buy[i]=Math.max(buy[i],sell[i-1]-price);
sell[i]=Math.max(sell[i],buy[i]+price);
}
}
return sell[k-1];
}
}
算法学习自黑马的数据结构与算法~