Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

腾讯&leetcode121:买卖股票的最佳时机 #96

Open
sisterAn opened this issue Aug 18, 2020 · 2 comments
Open

腾讯&leetcode121:买卖股票的最佳时机 #96

sisterAn opened this issue Aug 18, 2020 · 2 comments

Comments

@sisterAn
Copy link
Owner

sisterAn commented Aug 18, 2020

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。

注意:你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0

附赠leetcode地址:leetcode

@sisterAn
Copy link
Owner Author

sisterAn commented Aug 18, 2020

解法:动态规划

动态规划(Dynamic Programming,DP)是一种将复杂问题分解成小问题求解的策略,但与分治算法不同的是,分治算法要求各子问题是相互独立的,而动态规划各子问题是相互关联的。

分治,顾名思义,就是分而治之,将一个复杂的问题,分成两个或多个相似的子问题,在把子问题分成更小的子问题,直到更小的子问题可以简单求解,求解子问题,则原问题的解则为子问题解的合并。

我们使用动态规划求解问题时,需要遵循以下几个重要步骤:

  • 定义子问题
  • 实现需要反复执行解决的子子问题部分
  • 识别并求解出边界条件

第一步:定义子问题

动态规划是将整个数组归纳考虑,假设我们已经知道了 i-1 个股票的最大利润为 dp[i-1],显然 i 个连续股票的最大利润为 dp[i-1] ,要么就是就是 prices[i] - minpriceminprice 为前 i-1 支股票的最小值 ),在这两个数中我们取最大值

第二步:实现需要反复执行解决的子子问题部分

dp[i] = Math.max(dp[i−1], prices[i] - minprice)

第三步:识别并求解出边界条件

dp[0]=0

最后一步:把尾码翻译成代码,处理一些边界情况

因为我们在计算 dp[i] 的时候,只关心 dp[i-1]prices[i],因此不用把整个 dp 数组保存下来,只需设置一个 max 保存 dp[i-1] 就好了。

代码实现(优化):

let maxProfit = function(prices) {
    let max = 0, minprice = prices[0]
    for(let i = 1; i < prices.length; i++) {
        minprice = Math.min(prices[i], minprice)
        max = Math.max(max, prices[i] - minprice)
    }
    return max
}

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

leetcode

@Glittergalaxy
Copy link

Glittergalaxy commented Aug 18, 2020

function maxProfit(arr) {
  let min = arr[0], max = 0;
  for(let i = 0; i < arr.length; i ++) {
      min = Math.min(arr[i], min);
      max = Math.max(max, arr[i] - min);
  }
  return max;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants