【每日力扣】491. 非递减子序列与122. 买卖股票的最佳时机 II

在这里插入图片描述

🔥 个人主页: 黑洞晓威
😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害。

491. 非递减子序列

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

示例 1:

输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

示例 2:

输入:nums = [4,4,3,2,1]
输出:[[4,4]]

解题思路

要找出数组中的递增子序列,可以采用回溯法(Backtracking)进行求解。回溯法是一种通过尝试所有可能的候选解来求解问题的方法。在这个问题中,我们需要按照一定的规则来构建递增子序列,并记录下符合条件的结果。

具体的解题思路如下:

  1. 定义一个递归函数 backtrack,传入以下参数:
    • start:当前处理的起始位置。
    • path:当前的递增子序列。
  2. 在递归函数中,从 start位置开始遍历数组,对于每个元素,判断是否可以将其加入到当前的子序列中:
    • 如果可以加入(即当前元素大于等于子序列的最后一个元素),则将其加入到 path 中,并递归调用 backtrack 函数继续处理下一个位置。
    • 处理完当前位置后,需要将当前元素从 path 中移除,以便尝试其他可能的组合。
  3. 在递归的过程中,如果发现当前的 path 中至少有两个元素,则将其加入到结果集中。

代码

import java.util.ArrayList;
import java.util.List;

public class IncreasingSubsequences {

    public List<List<Integer>> findSubsequences(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        backtrack(nums, 0, path, result);
        return result;
    }

    private void backtrack(int[] nums, int start, List<Integer> path, List<List<Integer>> result) {
        if (path.size() >= 2) {
            result.add(new ArrayList<>(path));
        }
        if (start >= nums.length) {
            return;
        }

        // 使用 Set 避免重复元素
        Set<Integer> used = new HashSet<>();
        for (int i = start; i < nums.length; i++) {
            if (!used.contains(nums[i]) && (path.isEmpty() || nums[i] >= path.get(path.size() - 1))) {
                path.add(nums[i]);
                used.add(nums[i]);
                backtrack(nums, i + 1, path, result);
                path.remove(path.size() - 1);
            }
        }
    }

    public static void main(String[] args) {
        int[] nums1 = {4, 6, 7, 7};
        int[] nums2 = {4, 4, 3, 2, 1};

        IncreasingSubsequences solution = new IncreasingSubsequences();
        List<List<Integer>> result1 = solution.findSubsequences(nums1);
        List<List<Integer>> result2 = solution.findSubsequences(nums2);

        System.out.println(result1);
        System.out.println(result2);
    }
}

122. 买卖股票的最佳时机 II

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润

示例 1:

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

示例 2:

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

解题思路

要计算能获得的最大利润,可以采用贪心算法的思想。贪心算法的核心思想是每一步都选择当前状态下最优的选择,从而希望能够得到全局最优解。

具体解题思路如下:

  1. 遍历股票价格列表,计算相邻两天的价格差,如果价格差为正数,则表示可以在这两天进行交易,并且利润增加。
  2. 将所有正数的价格差相加,即可得到总利润。

代码

public class MaxProfitII {

    public int maxProfit(int[] prices) {
        int maxProfit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1]) {
                maxProfit += prices[i] - prices[i - 1];
            }
        }
        return maxProfit;
    }

    public static void main(String[] args) {
        int[] prices1 = {7, 1, 5, 3, 6, 4};
        int[] prices2 = {1, 2, 3, 4, 5};

        MaxProfitII solution = new MaxProfitII();
        System.out.println(solution.maxProfit(prices1)); // Output: 7
        System.out.println(solution.maxProfit(prices2)); // Output: 4
    }
}

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑洞晓威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值