• 贪心算法 - 买卖股票的最佳时机|| + 分割平衡字符串


    目录

    1.买卖股票的最佳时机||

    1.1 解题思路1:动态规划

    1.2 解题思路2:贪心

    2.分割平衡字符串

    2.1 解题思路 - 贪心


    1.买卖股票的最佳时机||

    题目描述:

    1. 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
    2. 在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。
    3. 你也可以先购买,然后在同一天出售。返回你能获得的最大利润 。

    示例 1:

    1. 输入:prices = [7,1,5,3,6,4]
    2. 输出:7
    3. 解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出,
    4. 这笔交易所能获得利润 = 5 - 1 = 4
    5. 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,
    6. 这笔交易所能获得利润 = 6 - 3 = 3
    7. 总利润为 4 + 3 = 7

    示例 2:

    1. 输入:prices = [1,2,3,4,5]
    2. 输出:4
    3. 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出,
    4. 这笔交易所能获得利润 = 5 - 1 = 4
    5.   总利润为 4

    提示:

    1. 1 <= prices.length <= 3 * 104
    2. 0 <= prices[i] <= 104

    🍁题目解析

    从题目中可以明确,任何时候,我们手里最多可以持有一股股票,我们可以在当天卖掉,也可以过几天再卖。我们的最终要求就是要通过不断对比今天和昨天的股票,然后选择最佳时机买卖股票,从而获得最大利润并返回。

    1.1 解题思路1:动态规划

    因为不能同时持有两股股票,所以每天交易结束后,我们持有的股票状态就只有两种:

    1.手里没有股票;

    2.手里持有一股股票。

    因此我们就可以讨论这两种情况下每天交易完成之后,我们能获得的最大利润是多少。由于每一天的利润只和前一天有关,于是得出:

    🍃1.第 i 天交易完之后,手里没有股票的最大利润

    dp0 [i] = max( dp0 [i - 1], dp1 [i - 1] + prices [i] )

     

     🍃2.第 i 天交易完成之后,手里持有一股股票的最大利润

    dp1 [i] = max(dp0 [i - 1] - prices [i], dp1 [i - 1])

    所以我们只要从前往后依次计算状态即可。由于全部交易结束后,持有股票的利润一定低于不持有股票的利润,所以最终返回 dp0.

    代码示例

    1. public int maxProfit(int[] prices) {
    2. // 第一天没买股票
    3. int dp0 = 0;
    4. // 第一天买了股票
    5. int dp1 = -prices[0];
    6. // 分情况讨论
    7. for(int i = 1; i < prices.length; i++) {
    8. // 1.第 i 天交易完之后,手里没有股票的最大利润
    9. dp0 = Math.max(dp0 , dp1 + prices[i]);
    10. // 2.第 i 天交易完成之后,手里持有一股股票的最大利润
    11. dp1 = Math.max(dp1,dp0 - prices[i]);
    12. }
    13. return dp0;
    14. }

    复杂度分析

    时间复杂度:O(n),只遍历一遍数组。

    空间复杂度:此处做了空间优化,只用到了常数个空间。

    1.2 解题思路2:贪心

    贪心的本质就是将原问题拆成很多子问题,分而治之的思想。所以我们可以划区间来判断,什么时候入股,什么时候卖掉。

    🍃1.当出现递增区间的时候,我们从第一个递增的位置开始入股;

    🍃2.在递增区间的结束位置卖掉,此时 我们的利润是最大的。

    利润 = (5 - 1)+ (6 - 3)= 7

    代码示例

    1. public int maxProfit(int[] prices) {
    2. int profit = 0;
    3. for(int i = 0; i < prices.length - 1; i++) {
    4. if(prices[i] < prices[i + 1]) {
    5. // 将递增区间的利润全部加起来就是最大利润
    6. profit += (prices[i + 1] - prices[i]);
    7. }
    8. }
    9. return profit;
    10. }

    复杂度分析

    时间复杂度:O(n),只遍历一遍数组

    空间复杂度:O(1)

    2.分割平衡字符串

    题目描述:

    1. 在一个平衡字符串 中,'L''R' 字符的数量是相同的。
    2. 给你一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
    3. 注意:分割得到的每个字符串都必须是平衡字符串,且分割得到的平衡字符串是原平衡字符串的连续子串。
    4. 返回可以通过分割得到的平衡字符串的 最大数量 。

    示例 1:

    1. 输入:s = "RLRRLLRLRL"
    2. 输出:4
    3. 解释:s 可以分割为 "RL""RRLL""RL""RL" ,每个子字符串中都包含相同数量的 'L''R'

    示例 2:

    1. 输入:s = "RLLLLRRRLR"
    2. 输出:3
    3. 解释:s 可以分割为 "RL""LLLRRR""LR" ,每个子字符串中都包含相同数量的 'L''R'

    提示:

    1. 1 <= s.length <= 1000
    2. 。s[i] = 'L''R'
    3. 。s 是一个平衡字符串

    2.1 解题思路 - 贪心

    贪心的本质就是将原问题拆成很多子问题,分而治之的思想。所以我们可以用一个变量 balance 从左到右依次找能被分割的子字符串。

    🍃1.遇到 "L",balance += 1;

    🍃2.遇到 "R",balance -= 1;

    🍃3.当 balance == 0 的时候,说明这个子字符串是一串平衡字符串,于是而已通过变量 count 来统计。

    代码示例

    1. public static int balancedStringSplit(String s) {
    2. // 平衡变量,数据达到平衡,就分割
    3. int balance = 0;
    4. // 统计分割出来的平衡字符串个数
    5. int count = 0;
    6. // 规定遇到 "L" 就 + 1,遇到 "R" 就 - 1
    7. for(int i = 0; i < s.length(); i++) {
    8. if(s.charAt(i) == 'L') {
    9. balance += 1;
    10. } else {
    11. balance -= 1;
    12. }
    13. // 平衡条件
    14. if(balance == 0) {
    15. count++;
    16. }
    17. }
    18. return count;
    19. }

    复杂度分析

    时间复杂度:O(n),只遍历一遍字符串

    空间复杂度:O(1)


    谢谢观看!!

  • 相关阅读:
    已解决ModuleNotFoundError: No module named ‘requests‘
    海思HI3798M GPIO和PWM操作
    一套基于 SpringBoot 和 Vue 的企业级中后台 java 开源项目
    Electron:WARNING Too many active WebGL contexts. Oldest context will be lost.
    Vue | Vue.js 实现过渡动画
    C#(二十八)之C#鼠标事件、键盘事件
    Kyuubi
    linux统计目录文件数量
    用友携YonSuite亮相云栖大会,全方位生态合作再提速
    开源大数据工具整理
  • 原文地址:https://blog.csdn.net/xaiobit_hl/article/details/126678235