❝If you wish to survive, you need to cultivate a strong mental attitude.
❞
如果你想活着,需要培养一颗坚强的心。
概述
盘点面试中常问的买卖股票的哪些题,程序哥这里整理出来并附上答案了,文末有程序哥在春招和秋招过程中整理的面试常见问题的PDF,欢迎公众号后台留言,免费赠送!!!
- 买卖股票的最佳时机【只能1次】
- 买卖股票的最佳时机【可2次】
- 买卖股票的最佳时机【不限次】
- 买卖股票的最佳时机【含冷冻期】
- 买卖股票的最佳时机【含手续费】
- 两人轮流在桌子上放硬币,谁会胜利【附加题】
1 买卖股票的最佳时机【只能1次】
❝给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。
❞
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
「答案」
只需要关心当前值和历史最小值,就可以了。
public static int maxProfit(int[] prices) {
int result = 0;
int min = Integer.MAX_VALUE;
for (int num : prices) {
min = Math.min(min, num);
result = Math.max(result, num - min);
}
return result;
}
2 买卖股票的最佳时机【可2次】
❝核心:就当是同一天买卖,两次,
❞
「答案」
public int maxProfit(int[] prices) {
int minPrice1 = Integer.MAX_VALUE;
int maxProfit1 = 0;
int maxProfitAfterBuy = Integer.MIN_VALUE;
int maxProfit2 = 0;
for(int price : prices) {
// 1.第一次最小购买价格
minPrice1 = Math.min(minPrice1, price);
// 2.第一次卖出的最大利润
maxProfit1 = Math.max(maxProfit1, price - minPrice1);
// 3.第二次购买后的剩余净利润
maxProfitAfterBuy = Math.max(maxProfitAfterBuy, maxProfit1 - price );
// 4.第二次卖出后,总共获得的最大利润(第3步的净利润 + 第4步卖出的股票钱)
maxProfit2 = Math.max(maxProfit2, price + maxProfitAfterBuy);
}
return maxProfit2;
}
3 买卖股票的最佳时机【不限次】
❝设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
❞
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3
「答案」
// 多次
public static int maxProfit(int[] prices) {
int res = 0;
// 多次买卖,利润最大的话,就需要在每相连的上升阶段买卖就可以了
for(int i =0; i <prices.length-1; i++){
if(prices[i+1] - prices[i] > 0){
res += prices[i+1] - prices[i];
}
}
return res;
}
4 买卖股票的最佳时机【含冷冻期】
❝卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
❞
「答案」
public static int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
// 定义三个数组 表示三种状态,
int n = prices.length;
int[] A = new int[n];// 观望 第i天A状态的最佳利润
int[] B = new int[n]; // 持股-prices
int[] C = new int[n]; // 冷却+prices
A[0] = 0;
B[0] = C[0] - prices[0];
for (int i = 1; i < n; i++) {
// 变为A状态有两种,a-A 和 c-a
A[i] = Math.max(A[i - 1], C[i - 1]);
//变为B状态有两种,b-b,A-b
B[i] = Math.max(B[i - 1], A[i - 1] - prices[i]);
// 变为C只有一种情况
C[i] = B[i - 1] + prices[i];
}
return Math.max(A[n - 1], C[n - 1]);
}
5 买卖股票的最佳时机【含手续费】
❝输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
❞
输出: 8
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
「答案」
public static int maxProfit(int[] prices, int fee) {
int len = prices.length;
if (len < 2) {
return 0;
}
// dp[i][j] 表示【0,i】区间内,到第1天状态为j时候的最大收益
//j = 0 表示不持股,j = 1表示持股
int[][] dp = new int[len][2];
dp[0][0] = 0; // 不持股
dp[0][1] = -prices[0] - fee; //持股
for (int i = 1; i < len; 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][0] -prices[i] - fee);
}
return dp[len-1][0];
}
6 两人轮流在桌子上放硬币,谁会胜利
❝两个人在圆桌子上轮流下硬币,规定最后一个人下硬币的时候并且刚好占满桌面,问是否有必胜的方法?
❞
「答案」 其实很简单哈,只要第一个下硬币,并且放在桌子的正中心,之后根据对称性,可以保障第一个人必赢。
面经PDF分享
- 公众号后台回复【加群】,程序哥看到后会第一时间分享。
本文使用 mdnice 排版