引言
由 “LSGO软件技术团队” 组织的 “基础算法刻意练习” 采用分类别练习的模式,即选择了五个知识点(数组、链表、字符串、树、贪心算法),每个知识点选择了 三个简单、两个中等、一个困难 等级的题目,共计三十道题,利用三十天的时间完成这组刻意练习。以下是我的每日打卡记录:
Task25.买卖股票的最佳时机 II
-
Leetcode第122题
-
难度:简单
-
题目概述:
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交 易(多次买卖一支股票)。 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票) 示例 1: 输入: [7,1,5,3,6,4] 输出: 7 解释: 在第2天(股票价格 = 1)的时候买入,在第3天(股票价格 = 5) 的时候卖出, 这笔交易所能获得利润=5-1=4 。随后,在第4天(股票价 格=3)的时候买入,在第5天(股票价格 = 6)的时候卖出, 这笔交易所 能获得利润=6-3=3 。 示例 2: 输入: [1,2,3,4,5] 输出: 4 解释: 在第1天(股票价格=1)的时候买入,在第5天 (股票价格=5)的 时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 示例 3: 输入: [7,6,4,3,1] 输出: 0 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
题解思路
将数组的值画成折线以后,我们可以看到,想要获得最大利润,只需要把每个低谷和高峰的差值相加即可,所以我们只需要找到每个低谷和每个高峰即可。
时间复杂度:O(n)
class Solution {
public int maxProfit(int[] prices) {
int n=prices.length;
int result=0;
for(int i=0;i<n;i++){
//找到 "谷"
while(i<n-1 && prices[i]>prices[i+1]) i++;
int min=prices[i];
//找到 "蜂"
while(i<n-1 && prices[i]<prices[i+1]) i++;
int max=prices[i];
result+=max-min;
}
return result;
}
}
提交记录
由思路一我们知道,只要把 “谷蜂” 差值都相加即可,那么代码可以简化为:
class Solution {
public int maxProfit(int[] prices) {
int result=0;
for(int i=0;i<prices.length-1;i++)
if(prices[i]<prices[i+1])
result+=prices[i+1]-prices[i];
return result;
}
}
动态规划是完全可行的,但是本题中,用动态规划其实有些 “杀鸡焉用牛刀” 的感觉,贪心算法完全足够解决这道求最优解的题目,但是还是要走个形式,贴个代码。
时间复杂度:O(n)
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
if (n<2)
return 0;
int[][] dp = new int[n][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < n; 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]);
}
return dp[n - 1][0];
}
}