day24-数据结构力扣

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

题目链接 122. 买卖股票的最佳时机 II - 力扣(LeetCode)

思路

这个题感觉和之前一个题有点像,就是摆动序列,但是又有点不太一样

本题的核心规则:

  • 可以无限次买卖

  • 任何时候最多持有 1 股

  • 同一天可以买了再卖

  • 求最大利润

只要后一天价格 > 前一天价格,就把这两天的差价赚到手。所有上涨日的差价加起来 = 最大利润。

**为什么正确?**连续上涨(1→2→3→4→5),每天赚差价:(2-1)+(3-2)+(4-3)+(5-4) = 5-1,和一次买卖结果完全一样

两个题的区别:

  • 股票题 :只赚涨的钱,跌的不碰

  • 摆动序列 :交替涨跌都算,统计最长长度

提交

很神奇,我以为会是很复杂的手段,结果和我想的不一样,有一种四两拨千斤的感觉

仿佛大脑的褶皱被抚平

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0
        # 从第2天开始遍历
        for i in range(1, len(prices)):
        # 只要今天比昨天贵,就赚差价
            if prices[i] > prices[i-1]:
                profit += prices[i] - prices[i-1]
        return profit

55. 跳跃游戏

题目链接 55. 跳跃游戏 - 力扣(LeetCode)

思路

首先,我没看懂题的意思?又开始阅读理解了

规则:

  • 数组 nums[i]:在位置 i 最多能跳几步

  • 起点:下标 0

  • 目标:判断能不能到达最后一个下标

示例 1: 输入:nums = 2,3,1,1,4

输出:true 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

我懂了,每个数组位置数字,是最多能跳几步

核心思想

  1. 用一个变量 max_reach 记录当前能跳到的最远位置

  2. 遍历数组,每到一个位置,就更新最远能跳到哪

  3. 如果遍历的位置超过了最远可达位置 ,说明卡住了,直接返回 false

  4. 如果最远位置 >= 最后一个下标 ,直接返回 true

一句话:只要当前位置还能跳到,就不断更新最远跳跃距离。

提交

python 复制代码
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        max_reach = 0  # 记录当前能跳到的最远下标
        n = len(nums)
    
        for i in range(n):
            # 如果当前位置都跳不到,直接失败
            if i > max_reach:
                return False
        
            # 更新最远能跳到的位置
            max_reach = max(max_reach, i + nums[i])
        
            # 已经能跳到终点,提前返回
            if max_reach >= n - 1:
                return True
    
        return True

45.跳跃游戏II

题目链接 45. 跳跃游戏 II - 力扣(LeetCode)

思路

这简直就是55跳跃游戏的plus版本

  • 核心逻辑 :不关心每一步具体跳到哪个位置,只关心当前能到达的最远位置,当遍历到当前跳跃的边界时,必须进行一次跳跃,同时更新边界为新的最远位置。

  • 三个关键变量:

    • jumps:记录最小跳跃次数(最终结果)

    • current_end:当前这一步能到达的最远边界

    • farthest:遍历过程中能到达的全局最远位置

  • 遍历规则:

    • 遍历数组(不需要遍历最后一个元素,因为到了最后一个元素就已经到达终点)

    • 每遍历一个位置,更新能到达的最远位置 farthest

    • 当遍历到 current_end 时,说明必须跳一步,jumps+1,并把 current_end 更新为 farthest

以 nums = [2,3,1,1,4] 为例:

  1. 初始:jumps=0, current_end=0, farthest=0
  2. i=0 :
    • farthest = max(0, 0+2) = 2
    • i == current_end → jumps=1,current_end=2
  3. i=1 :
    • farthest = max(2, 1+3) = 4
  4. i=2 :
    • farthest = max(4, 2+1) = 4
    • i == current_end → jumps=2,current_end=4(已经到达终点,退出)
  5. 最终返回 2

提交

python 复制代码
class Solution:
    def jump(self, nums: List[int]) -> int:
        n = len(nums)
        jumps = 0  # 记录跳跃次数
        current_end = 0  # 当前跳跃的边界
        farthest = 0  # 能到达的最远位置

        # 不需要遍历最后一个元素,因为已经到达终点
        for i in range(n - 1):
            # 更新最远能到达的位置
            farthest = max(farthest, i + nums[i])
            
            # 到达当前边界,必须跳一次
            if i == current_end:
                jumps += 1
                current_end = farthest
                
                # 优化:如果已经能跳到终点,直接提前退出
                if current_end >= n - 1:
                    break
        return jumps

1005.K次取反后最大化的数组和

题目链接1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

思路

依旧还是先做阅读理解

k是指可以选择k个数字将他们的正负号反转,但是具体反转那个不知道。

有不同的反转方案

我们要得到最佳方案,就是这些方法里面数组之和最大的那个结果

第一版思路:通过66/84

可以先把数组排序,我们反转数组里面较小的数字

对于正数:反转之后减的最少,那就是反最小的正数

对于负数:反转之后加的最大,反负更多的,也就是更小的负数

比如【4,2,3】k=1,排序【2,3,4】就是反转2

【2,-3,-1,5,-4】k=2,排序【-4,-3,-1,2,5】反转-4,-3

但是有一种特殊情况 就是有0的:

因为题目说有些下标是可以多次反转的

那我们把负的反过来之后,还有次数就反转0

这里正数部分应该单独处理

比如把正数反转之后,我们应该找修改数组后的最小值反转

而不是继续遍历反转

提交

python 复制代码
from typing import List

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        # 从小到大排序,优先翻转最小的负数(收益最大)
        nums.sort()
        
        for i in range(len(nums)):
            if nums[i]<0:
                # 翻转当前最小负数为正数,消耗一次翻转次数
                nums[i] = -nums[i]
                k -= 1
                if k == 0:
                    # 翻转次数用完,直接退出
                    break
            elif nums[i]==0:
                # 遇到0,剩余次数全部翻转0,总和不变
                k = 0
                break
            else:
                # 后面全是正数,无需继续翻转
                break

        if k>0 and k%2==1:
            # 剩余奇数次翻转,必须翻转一次最小值(损失最小)
            num=min(nums)
            index=nums.index(num)
            nums[index]=-nums[index]

        return sum(nums)
相关推荐
小郎君6581 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧1 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
hold?fish:palm1 小时前
40 二叉树的直径
c++·leetcode
Shimeri2 小时前
越卷越像:我用遗传算法做了个"内卷"实验
算法·three.js·数据可视化·遗传算法·进化算法
Evand J2 小时前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波
guo_wen_qiang2 小时前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖2 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
CCblandy3 小时前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化
上班摸鱼下班游戏3 小时前
Unity 仿生智能算法 从蚁群算法 开始
算法·unity·游戏引擎
pipixia200333 小时前
C++ 面试高频:namespace 的 6 个知识点,从 using 到匿名命名空间
c语言·学习·算法·嵌入式·命名空间·c++面试·匿名命名空间