【LeetCode Hot100 贪心算法】 买卖股票的最佳时机、跳跃游戏、划分字母区间

devtools/2025/1/12 18:08:27/

贪心算法

    • 买卖股票的最佳时机
    • 买卖股票的最佳时机II
    • 跳跃游戏
    • 跳跃游戏II
    • 划分字母区间

买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

思路
如果第 i i i 天卖出股票,则最大利润为(该天的股价-前面天数中最小的股价),然后与已知的最大利润比较,如果大于则更新当前最大利润的值。

代码

class Solution {public int maxProfit(int[] prices) {int cost = Integer.MAX_VALUE, profit = 0;for (int i = 0; i < prices.length; i++) {cost = Math.min(cost, prices[i]);profit = Math.max(profit, prices[i] - cost);}return profit;}
}

买卖股票的最佳时机II

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

思路
分解成每天都买卖,但是只在最后的结果中加入正的,局部最优->全局最优。

代码
注意 i 从 1 开始

class Solution {public int maxProfit(int[] prices) {int profit = 0;for (int i = 1; i< prices.length; i++) {profit += Math.max(prices[i] - prices[i-1], 0);}return profit;}
}

跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

思路
确定从第一个位置开始,能够跳跃到的范围有多少,如果这个范围能够覆盖到数组的最后一个位置,那么就可以范围true。

代码

class Solution {public boolean canJump(int[] nums) {int cover = 0; // 覆盖范围// 遍历的范围是cover内for (int i = 0; i <= cover; i++) {// 遍历到一个位置,就从上一个cover和该位置能够到达的最远位置取最大值cover = Math.max(cover, i + nums[i]);if (cover >= nums.length - 1) {// 如果能够覆盖到数组的最后一个位置return true;}}return false;}
}

跳跃游戏II

在上一题的基础上,要求返回最少跳跃次数。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

思路
在这里插入图片描述
代码

class Solution {public int jump(int[] nums) {int curRight = 0;   // 已经造桥的右端点int nextRight = 0;  // 下一步造桥最远的端点int ans = 0;  // 答案// for 循环中 i < nums.length - 1// 因为开始的时候边界时第0个位置,ans已经加过一次1了,最后末尾的时候不用计算步数了for (int i = 0; i < nums.length - 1; i++) {nextRight = Math.max(nextRight, i + nums[i]);if (i == curRight) {   // 到达已建造的桥的右端点curRight = nextRight;  // 建造桥ans++;}}return ans;}
}

划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:s = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、“defegde”、“hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。
示例 2:
输入:s = “eccbbbbdec”
输出:[10]

思路
先用一个hash数组把字符串中每一个字母出现的最远位置下标存储在hash数组中。
遍历字符串,更新当前要划分的区间的最远距离(当前最远距离与该位置字母的最远位置下标取最大值)
然后判断此时的最远位置是否是当前位置,如果是说明已经找到了一个划分的区间。
结合代码随项目的思路来解题

代码

class Solution {public List<Integer> partitionLabels(String s) {int[] hash = new int[26];for (int i = 0; i < s.length(); i++) {// 求某个字母的最远位置;使用hash来记录;// s.charAt(i) - 'a'是字母的索引,i是这个字母目前的最远位置hash[s.charAt(i) - 'a'] = i;}int left = 0, right = 0;List<Integer> ans = new ArrayList<>();for (int i = 0; i < s.length(); i++) {// 现有的右边界和当前位置字母的最远出现位置求maxright = Math.max(right, hash[s.charAt(i) - 'a']);// i == right 说明找到了一个分割点if (i == right) {ans.add(right - left + 1);left = right + 1; }  }return ans;}
}

http://www.ppmy.cn/devtools/149938.html

相关文章

C# OpenCV机器视觉:主色提取

在一个忙碌的工作日&#xff0c;小李正对着电脑屏幕上密密麻麻的数据愁眉苦脸&#xff0c;突然&#xff0c;手机铃声大作&#xff0c;打破了办公室的宁静。原来是工厂的张厂长打来的电话&#xff1a;“小李啊&#xff0c;咱们新生产的那批产品&#xff0c;客户要求必须提取出主…

【日常小记】Ubuntu启动后无图形界面且网络配置消失

【日常小记】Ubuntu启动后无图形界面且网络配置消失 解决方法&#xff1a; 1. 输入后恢复网络: #sudo dhclient 2. 重新安装ubuntu-desktop #sudo apt-get install ubuntu-desktop&#xff01;&#xff01;&#xff01;请关注是否能ping通某网站&#xff08;例如百度&…

X64汇编语言教程(白帽黑客系列课程)(五)

为什么要写这篇教程呢&#xff1f; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 因为想要成为一名白帽黑客&#xff0c;汇编语言是必须要掌握的&#xff01; 无论是二进制漏洞挖掘&#xff0c;还是逆向工程&#xff01;汇编语言&#xff0c;都是硬性基础…

10分钟快速了解OceanGPT(沧渊)

10分钟快速了解OceanGPT(沧渊) 海洋科学任务的大语言模型——OceanGPT OceanGPT是如何训练的?为了训练 OceanGPT (沧渊) ,收集了一个跨越多个领域的海洋科学语料库。由于每个子领域和主题都有其独特的数据特征和模式,因此提出了一个特定于领域的指令生成框架,称为 DoDirec…

第5天:APP应用微信小程序原生态开发H5+Vue技术封装打包反编译抓包点

知识点&#xff1a; 1、基础入门-APP应用-开发架构安全问题 2、基础入门-小程序应用-开发架构安全问题 APP应用开发架构&#xff1a; 1、原生开发 安卓一般使用java语言开发&#xff0c;当然现在也有kotlin语言进行开发。如何开发就涉及到具体编程了&#xff0c;这里就不详说了…

Qt天气预报系统获取天气数据

Qt天气预报系统获取天气数据 1、获取天气数据1.1添加天气类头文件1.2定义今天和未来几天天气数据类1.3定义一个解析JSON数据的函数1.4在mainwindow中添加weatherData.h1.5创建今天天气数据和未来几天天气数据对象1.6添加parseJson定义1.7把解析JSON数据添加进去1.8添加错误1.9解…

正则表达式完全指南

# 正则表达式完全指南 正则表达式&#xff08;Regular Expression&#xff0c;简称 regex 或 regexp&#xff09;是一种强大的文本匹配和处理工具。它使用特定的语法规则来描述字符串的匹配模式&#xff0c;广泛应用于文本搜索、替换和数据验证等场景。 ## 1. 基础语法 ### 1.1…

Ruby语言的正则表达式

Ruby语言的正则表达式详解 正则表达式&#xff08;Regular Expressions&#xff0c;简称Regex&#xff09;是一种强大的文本处理工具&#xff0c;它可以用来匹配、搜索、替换字符串中的模式。在Ruby语言中&#xff0c;正则表达式的使用非常灵活&#xff0c;并且具有良好的可读…