13-贪心
📅 发表于 2026/06/07
🔄 更新于 2026/06/07
👁️ -- 次访问
📝 0 字
⏳ 0 分钟
prices,代表一只股票每天的价格。可以购买卖出。只能买1次、卖1次。最大收益。7,1,5,3,6,4] --> 5price=1,第5天卖出price=6,收益=6-1=5两个关键变量
历史最低价:一直遍历更新。今日卖出最大利润:今日价格-历史最低价最大利润:每日最大利润最大值贪心
历史最低价 买入。min_price最高点 卖出。max_profit遍历计算
历史最低价格买,今日卖的利润最大利润历史最低价格def maxProfit(self, prices: List[int]) -> int:
if not prices or len(prices) == 1:
return 0
# 历史最低价格
min_price = prices[0]
# 最大利润
max_profit = 0
# 依次计算,按照历史最低价格买入,每天卖出获得的利润
for price in prices[1:]:
# 历史最低价格买,今日卖的利润
profit = price - min_price
# 更新最大利润
max_profit = max(max_profit, profit)
# 更新历史最低价格
min_price = min(price, min_price)
return max_profit某只股票每日价格 prices 数组。最多只能持有 1股股票,可以多次买卖股票。最大利润示例
第2天买,第3天卖:利润=5-1=4第4天买,第5天卖:利润=6-3=3总利润:4+3=7总利润0牛市股票长线利润==每日增长之和
总涨幅 == 每日微小涨幅之和总利润:8-3=5总利润:2+3=5贪心策略
today 和yesterdaytoday > yesterday:涨了,卖掉;把微小涨幅拿到手。today < yesterday:跌了,不管。求和 所有微小涨幅,即总利润。def maxProfit(self, prices: List[int]) -> int:
"""可多次买卖股票,求总利润,贪心算法,只需拿到每日微小总涨幅,求和即可"""
if not prices or len(prices) <= 1:
return 0
# 策略:昨天买,今天卖。
# 累计利润求和
sum_profit = 0
for i in range(1, len(prices)):
# 昨日价格
yesterday_price = prices[i-1]
# 今日价格
today_price = prices[i]
# 今日 > 昨日,则卖出,累计今日利润
if today_price > yesterday_price:
# 今日利润
today_profit = today_price - yesterday_price
# 每日利润累加
sum_profit += today_profit
return sum_profit非负整数数组 nums,数组元素表示当前位置 能跳跃的最大步数,最初位于位置0。能否到达最后一个位置。True FalseTrue。可先1步,再3步,到达最后位置。0,4] -> False。无论如何都会到达idx=3,但跳跃长度是0,无法跳跃。max_reach:最多能到达 哪个位置i > max_reach:不可到达,返回False贪心更新 max_reach:max (max_reach, i+nums[i])max_reach >= len(nums)-1,返回Truedef canJump(self, nums: List[int]) -> bool:
"""贪心法,解决可到达的最大位置"""
if not nums:
return False
# 可到达的最大位置
max_reach = 0
# 目标位置
target_pos = len(nums) - 1
for i, step in enumerate(nums):
if max_reach < i:
# 过去 max_reach 已无法到达当前i
return False
# 能到达当前i,当前i能到达的最大位置
cur_max_reach = i + step
# 贪心更新 可到达最大位置
max_reach = max(max_reach, cur_max_reach)
# 已能到达末尾位置
if max_reach >= target_pos:
return True
return False贪心
更新极限边界,走到边界就做结算。三元素
max_reach:下一步起跳潜力,下一步能到达的最远地方。 max_reach, i+nums[i])end:当前极限边界。到达这里就需重新起跳。 cur_step_end = max_reach,即 i+nums[i] 或 旧max_reachsteps:累计起跳步数。def jump(self, nums: List[int]) -> int:
"""跳跃到n-1,需要的最少步数,保证可到达,贪心算法"""
if not nums or len(nums) <= 1:
return 0
# 核心1:下一步起跳【最远能接力到哪里】。一路上谁的潜力大就听谁的。
max_reach = 0
# 核心2:当前这一步的【能量极限边界】。到了这里就必须强行触发起跳。
cur_step_end = 0
# 核心3:【总共跳了多少步】。
steps = 0
# 只需遍历到倒数第二个位置即可,否则到了末尾还会计算1次跳跃
for i in range(len(nums)-1):
# 贪心更新下一步起跳的最大位置
max_reach = max(max_reach, i+nums[i])
# 当前位置已到达当前步的最远位置,需要迈新的步子了
if i == cur_step_end:
cur_step_end = max_reach
steps += 1
return steps字符串s划分为多的片段。同一字母仅能在一个片段中。所有子串的长度列表ababcbaca defegde hijhklij --> [9, 7, 8]。eccbbbbdec --> [10]三要素
last_pos:记录每个ch的最后出现位置。开始位置。结束位置。遍历每个位置i-字符ch,寻找子串/片段
当前ch的最后出现位置 在当前片段里end = max(end, last_pos[i])i == end: [start,i]之间的所有ch 都在当前片段,未来 都不会出现找到片段:len = end-start+1更新 下一片段start:start = end + 1def partitionLabels(self, s: str) -> List[int]:
"""贪心分割子串,last_pos, start, end"""
if not s:
return []
# 记录每个ch的最后出现位置
ch2last = {}
for idx, ch in enumerate(s):
ch2last[ch] = idx
res = []
# 当前片段的起始值
start, end = 0, 0
# 依次遍历所有ch,查找所有可能片段
for i, ch in enumerate(s):
# 当前ch的最后出现位置
last_pos = ch2last[ch]
# 当前片段end 应该>=last_pos
end = max(end, last_pos)
if i == end:
# 说明[start, end]之间所有字符,当前片段都已包含,未来不会出现
cur_len = end - start + 1
res.append(cur_len)
# 下一片段起始值
start = end + 1
return res