力扣面试经典150 —— 6-10题

  • 力扣面试经典150题
  • 在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题,安装 Debug LeetCode 插件可以免费 debug
  • 本文使用 python 语言解题,文中 “数组” 通常指 python 列表;文中 “指针” 通常指 python 列表索引

文章目录

  • 6. [中等] 轮转数组
    • 6.1 解法1:使用额外的数组
    • 6.2 解法2:数组翻转
  • 7. [简单] 买卖股票的最佳时机
    • 7.1 解法1:暴力法
    • 7.2 解法2:贪心
  • 8. [中等] 买卖股票的最佳时机II
    • 8.1 解法1:贪心
    • 8.2 解法2:动态规划
  • 9. [中等] 跳跃游戏
    • 9.1 解法1:贪心模拟
    • 9.2 解法2:贪心
  • 10. [中等] 跳跃游戏II
    • 10.1 解法1:贪心模拟

6. [中等] 轮转数组

  • 题目链接
  • 标签:数组、数学、双指针
    在这里插入图片描述

6.1 解法1:使用额外的数组

  • 借助一个额外数据将各个元素放到新位置。注意到从整体上看,输出数组可以看作是在 k % len(nums) 位置截断然后重新组合,可以用 python 的列表操作简单地如下实现
    class Solution:
        def rotate(self, nums: List[int], k: int) -> None:
            k = k % len(nums)
            res = nums[-k:] + nums[:-k]
            nums[:] = res
    
    这其实等价于用两个指针分别遍历截断的两部分,并将元素依次复制到辅助数组
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)

6.2 解法2:数组翻转

  • 和方法一一样,注意到输出数组可以看作是在 k % len(nums) 位置截断然后重新组合,这可以通过三次列表翻转实现,示意如下
    nums = "----->-->"; k =3
    result = "-->----->";
    
    reverse "----->-->" we can get "<--<-----"
    reverse "<--" we can get "--><-----"
    reverse "<-----" we can get "-->----->"
    
    下面给出代码,使用双指针进行翻转操作
    class Solution:
        def rotate(self, nums: List[int], k: int) -> None:
            def _reverse(start, end):
                while start < end:
                    t = nums[start]
                    nums[start] = nums[end]
                    nums[end] = t
                    start += 1
                    end -= 1
    
            k = k % len(nums)
            _reverse(0, len(nums)-1)
            _reverse(0, k-1)
            _reverse(k, len(nums)-1)
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

7. [简单] 买卖股票的最佳时机

  • 题目链接
  • 标签:数组、动态规划
    在这里插入图片描述

7.1 解法1:暴力法

  • 直接遍历所有可能的买卖组合情况,但这种方法会超时
    def maxProfit(self, prices: List[int]) -> int:
            # 暴力法:超时
            profit = -float('inf')
            for i in range(len(prices)-1):
                buy = prices[i]
                for j in range(i+1, len(prices)):
                    sell = prices[j]
                    if sell > buy and sell - buy > profit:
                        profit = sell - buy
            profit = 0 if profit < 0 else profit
            return profit
    
  • 时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1)

7.2 解法2:贪心

  • 只遍历一遍,在每个时刻贪心地计算可能的最大利润。为此,需要动态地更新截止目前为止的最低买入价
    class Solution:
        def maxProfit(self, prices: List[int]) -> int:
            # 贪心:动态维护历史最低价,进而利用它计算理论最大收益
            min_price = float('inf')
            max_profit = -float('inf')
            for p in prices:
                # 动态维护历史最低价
                if p < min_price:
                    min_price = p
    
                # 基于历史最低价得到在当前时刻卖出的理论最大收益
                profit = p - min_price
                if profit > max_profit:
                    max_profit = profit
    
            max_profit = 0 if max_profit < 0 else max_profit
            return max_profit
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

8. [中等] 买卖股票的最佳时机II

  • 题目链接
  • 标签:贪心、数组、动态规划
    在这里插入图片描述

8.1 解法1:贪心

  • 基于贪心的思想,实现最大利润意味着每一次可能的盈利都被把握。我们变量把股价曲线折线图,在每一个时刻执行收益最大化操作,即把每一个上升段都加入总收益中,水平或下降段则跳过
    class Solution:
        def maxProfit(self, prices: List[int]) -> int:
            max_profit = 0
            for i in range(len(prices)-1):
                profit = prices[i+1] - prices[i]
                if profit > 0:
                    max_profit += profit
            return max_profit
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

8.2 解法2:动态规划

  • 题目设置满足动态规划的三要素
    1. 无后效性:当前和未来的交易操作不会影响过去交易操作的收益
    2. 最优子结构:在整个交易过程中实现最大收益,意味着交易过程中的任意一个时间段的收益都是最优的。问题最优解的结构包含其子问题的最优解
    3. 重叠子问题:当我们递归地自顶向下分解时,即把 “最大化前n天收益” 不断地递归分解为 “最大化前n-1天收益,同时最大化第n-1天收益” 时,出现了要在递归过程中重复求解的重叠子问题(比如 “最大化前1天收益”),这提示我们使用递推式自底向上的构造解(动态规划的自底向上形式),或使用带备忘录的递归法(动态规划的自顶向下形式)
  • 我们使用自底向上的动态规划形式,这时需要构造递推公式(动态规划中称 “状态转移方程”)。定义状态 dp[i][0]dp[i][1] 分别表示第 i i i 天交易完后手里没有和持有股票的最大利润。
    1. 对于 dp[i][0] 来说,第 i i i 天交易完后手里没有股票,意味着要么前一天就没有,要么今天卖了,递推式为
      d p [ i ] [ 0 ] = max ⁡ { d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] } dp[i][0]=\max\{dp[i−1][0],dp[i−1][1]+prices[i]\} dp[i][0]=max{dp[i1][0],dp[i1][1]+prices[i]}
    2. 对于 dp[i][1] 来说,第 i i i 天交易完后手里有股票,意味着要么前一天有,要么今天刚买,递推式为
      d p [ i ] [ 1 ] = max ⁡ { d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] } dp[i][1]=\max\{dp[i−1][1],dp[i−1][0]−prices[i]\} dp[i][1]=max{dp[i1][1],dp[i1][0]prices[i]}
    3. 根据问题定义,第0天交易时有
      d p [ 0 ] [ 0 ] = 0 , d p [ 0 ] [ 1 ] = − p r i c e s [ 0 ] dp[0][0]=0,\quad dp[0][1]=−prices[0] dp[0][0]=0,dp[0][1]=prices[0]
    4. 由于全部交易结束后,持有股票的收益一定低于不持有股票的收益,最后返回 d p [ n − 1 ] [ 0 ] dp[n−1][0] dp[n1][0] 即可
  • 注意到以上状态转移方程1、2中,dp[i] 仅与 dp[i-1] 有关,而与更早的状态都无关,因此不必存储这些无关的状态,只需要将 dp[i−1][0]dp[i−1][1] 存放在两个变量中,通过它们计算出 dp[i][0]dp[i][1] 并存回对应的变量,以便于第 i + 1 i+1 i+1 天的状态转移计算即可
    class Solution:
        def maxProfit(self, prices: List[int]) -> int:
            dp0 = 0             # 今日交易完后手里没有股票的最大利润
            dp1 = -prices[0]    # 今日交易完后手里有一支股票的最大利润
            for i in range(1, len(prices)):
                dp0_ = max(dp0, dp1 + prices[i])
                dp1_ = max(dp1, dp0 - prices[i])
                dp0, dp1 = dp0_, dp1_            
            return dp0
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

9. [中等] 跳跃游戏

  • 题目链接
  • 标签:贪心、数组、动态规划
    在这里插入图片描述

9.1 解法1:贪心模拟

  • 直接模拟整个转移过程,每次都贪心地跳到能去向的最远处,直到达到终点或无法前进
    class Solution:
        def canJump(self, nums: List[int]) -> bool:
            cur_pos = next_pos = 0
            max_range = nums[cur_pos]   # 当前可达的最大索引位置
            while True:
                # 若从当前位置可以直接到目标,退出
                if max_range >= len(nums) - 1:
                    return True
    
                # 考察从当前位置可达的每个新位置可覆盖的最大范围, 贪心地选择可达范围最大处作为转移到的索引位置 next_pos
                for steps in range(1, nums[cur_pos] + 1):
                    next_range = cur_pos + steps + nums[cur_pos + steps]
                    if next_range > max_range:
                        next_pos = cur_pos + steps
                        max_range = next_range
                
                # 如果当前位置已经是最佳的,且已知当前 max_range 无法到达目标,退出
                if next_pos == cur_pos:
                    return False
    
                # 去向新索引位置
                cur_pos = next_pos
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

9.2 解法2:贪心

  • 对于每一个可达位置 x x x,它使得 x + 1 , x + 2 , ⋯   , x + nums [ x ] x+1,x+2,⋯ ,x+\text{nums}[x] x+1,x+2,,x+nums[x] 这些连续的位置都可以到达。利用贪心的思想,我们遍历数组,并在每一步维护当前可达的最大状态,如果发现最后的位置可达则返回 true,反之若遍历结束后最后位置仍不可达则返回 false
    class Solution:
        def canJump(self, nums: List[int]) -> bool:
            max_range = 0
            for i, step in enumerate(nums):
                if i <= max_range:
                    if i + step > max_range:
                        max_range = i + step
                    if max_range >= len(nums) - 1:
                        return True
            return False
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

10. [中等] 跳跃游戏II

  • 题目链接
  • 标签:贪心、数组、动态规划
    在这里插入图片描述

10.1 解法1:贪心模拟

  • 和 9.1 完全一直,直接模拟整个转移过程,每次都贪心地跳到能去向的最远处,直到达到终点或无法前进。模拟的同时记录总跳跃次数并返回
    class Solution:
        def jump(self, nums: List[int]) -> int:
            # 特殊情况直接退出
            if len(nums) == 1:
                return 0
    
            cur_pos = next_pos = step_cnt = 0
            max_range = nums[cur_pos]
            while True:
                # 若从当前位置可以直接到目标,退出
                if max_range >= len(nums) - 1:
                    return step_cnt + 1
    
                # 考察每一个新位置可以覆盖的最大范围,next_pos 设置为范围最大新索引位置
                for steps in range(1, nums[cur_pos] + 1):
                    next_range = cur_pos + steps + nums[cur_pos + steps]
                    if next_range > max_range:
                        next_pos = cur_pos + steps
                        max_range = next_range
    
                # 去向新索引位置
                cur_pos = next_pos
                step_cnt += 1
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/440049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷歌浏览器打包扩展插件,提示清单文件缺失或不可读取

今天想把谷歌浏览器的扩展打包一下&#xff0c;放到我虚拟机的谷歌浏览器&#xff0c;但是一直打包不成功。 问题 打包扩展程序错误 提示‘清单文件缺失或不可读取’ 原因 路径没有选择正确&#xff01; 解决办法 1.首先找到google浏览器的安装路径。在谷歌浏览器地址栏输…

穷人想赚钱该怎么选打工VS创业?2024年如何把握新机遇?

在贫穷的困境中&#xff0c;打工与创业似乎成为了两条截然不同的道路&#xff0c;摆在每一个渴望改变命运的人面前。然而&#xff0c;这并非简单的选择题&#xff0c;而是一场关于勇气、智慧与机遇的较量。打工&#xff0c;对于许多人来说&#xff0c;是稳定且相对安全的收入来…

XSS靶场-DOM型初级关卡

一、环境 XSS靶场 二、闯关 1、第一关 先看源码 使用DOM型&#xff0c;获取h2标签&#xff0c;使用innerHTML将内容插入到h2中 我们直接插入<script>标签试一下 明显插入到h2标签中了&#xff0c;为什么不显示呢&#xff1f;看一下官方文档 尽管插入进去了&#xff0…

Java后端八股笔记

Java后端八股笔记 Redis八股 上两种都有可能导致脏数据 所以使用两次删除缓存的技术&#xff0c;延时是因为数据库有主从问题需要更新&#xff0c;无法达到完全的强一致性&#xff0c;只能达到控制一致性。 一般放入缓存中的数据都是读多写少的数据 业务逻辑代码&#x1f44…

双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的技术应用

原文链接&#xff1a;双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的技术应用https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&tempkeyMTI2MF9DVWNrMFpvV1d3RGxBZUE2QXJBRnI1NEJkcVhzRFZwakRqYXhhVFQzQnh1MVhJcy1laWh6Nmd4R…

[密码学]入门篇——加密方式

一、概述 加密方法主要分为两大类&#xff1a; 单钥加密&#xff08;private key cryptography&#xff09;&#xff1a;加密和解密过程都用同一套密码双钥加密&#xff08;public key cryptography&#xff09;&#xff1a;加密和解密过程用的是两套密码 历史上&#xff0c…

Redis与 Memcache区别

Redis与 Memcache区别 1 , Redis 和 Memcache 都是将数据存放在内存中&#xff0c;都是内存数据库。不过 Memcache 还可用于缓存 其他东西&#xff0c;例如图片、视频等等。 2 , Memcache 仅支持key-value结构的数据类型&#xff0c;Redis不仅仅支持简单的key-value类型的数据&…

vue2 element 实现表格点击详情,返回时保留查询参数

先直观一点&#xff0c;上图 列表共5条数据&#xff0c;准备输入Author过滤条件进行查询 进入查看详情页&#xff0c;就随便搞了个按钮&#xff0c;将就看吧 点击返回后 一开始准备用vuex做这个功能&#xff0c;后来放弃了&#xff0c;想到直接用路由去做可能也不错。有时间…

如何获取国外信用卡?需要国外银行卡支付怎么解决?如何订阅国外产品?

当国内的用户想要使用国外的产品时&#xff0c;很多产品是需要订阅付费的。其中有些产品还没有引入国内&#xff0c;只能用国外的信用卡支付&#xff0c;对于在国内的朋友&#xff0c;如何获取一张国外的信用卡呢&#xff1f; 这里推荐一个平台&#xff1a;wildCard waildCard…

基于SpringBoot的在线拍卖系统

目录 1、 前言介绍 2、主要技术 3、系统流程和逻辑 4、系统结构设计 5、数据库设计表 6、运行截图(部分) 6.1管理员功能模块 6.2用户功能模块 6.3前台首页功能模块 7、源码获取 基于SpringBoot的在线拍卖系统录像 1、 前言介绍 随着社会的发展&#xff0c;社会的各行…

力扣大厂热门面试算法题 6-8

6. Z 字形变换&#xff0c;7. 整数反转&#xff0c;8. 字符串转换整数 (atoi)&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.08 可通过leetcode所有测试用例。 目录 6. Z 字形变换 解题思路 边界条件 完整代码 Python Ja…

【手游联运平台搭建】游戏平台的作用

随着科技的不断发展&#xff0c;游戏行业也在不断壮大&#xff0c;而游戏平台作为连接玩家与游戏的桥梁&#xff0c;发挥着越来越重要的作用。游戏平台不仅为玩家提供了便捷的游戏体验&#xff0c;还为游戏开发者提供了广阔的市场和推广渠道。本文将从多个方面探讨游戏平台的作…

AWTK-MVVM 文件模型

AWTK-MVVM 文件模型 名称&#xff1a;file 功能&#xff1a;用于读写文件内容&#xff0c;浏览&#xff08;打开/保存&#xff09;文件。 内置属性 属性类型说明filenamestring文件名contentstring文件内容sizenumber文件大小auto_loadboolean是否自动加载文件内容is_dirtyb…

QT:用opencv的KNN识别图片中的LED数字(一)

前言 一款功能测试的软件demo,使用了QT作为界面,主要使用了opencv的KNN识别,使用gstreamer作为管道,用来打开图片。后期会写一篇打开摄像头实时识别的文章。 (正在写,未完成,稍候) 效果一预览: 效果二预览: 效果三预览: 正在写。。。 设计思路 1. 软件UI设…

关于阿里云服务器地域的选择方法,看这一篇就够了

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

亚洲股市下一步的关键:中国看财报、日本看汇率、韩国看治理、印度看基建

汇丰认为财报将是驱动中国股市走势的关键因素。目前市场预计2024年中国企业每股收益将增长16%。 日本央行转向、A股业绩复苏、印度基建、韩国市场改革......最近这段时间&#xff0c;亚洲各大市场涌现出了不同的交易主题。 汇丰银行指出&#xff0c;中国受到本土企业盈利能力…

直播美颜SDK开发:如何应对不同场景下的挑战?

直播美颜SDK的开发&#xff0c;便是为了满足这一需求&#xff0c;但面对不同场景下的挑战&#xff0c;开发者们需要克服各种技术难题&#xff0c;以确保美颜效果的稳定和自然。 首先&#xff0c;我们需要了解直播美颜SDK在不同场景下可能面临的挑战。这些挑战主要包括&#xff…

牛客论坛笔记~

文章目录 Redisspring整合redis实现点赞帖子的赞用户的赞 关注功能热帖排行redis存储验证码、登录凭证、用户信息 kafka阻塞队列kafka![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d35be55986344b548710985cd8ecbd87.png)触发事件处理事件 Redis高级网站数据统计…

【SSCI稀缺版面】最快录用仅2个月(内附录用发表时间节点)

录用案例 JCR4区经济管理类SSCI (进展顺) 【期刊简介】IF&#xff1a;0-1.0&#xff0c;JCR4区&#xff0c;中科院4区&#xff1b; 【检索情况】SSCI在检&#xff1b; 【征稿领域】计算机/数据建模在经济与管理决策绩效评价的形态应用相关研究均可&#xff1b; 【案例分享】…

​项目文章 | METTL3敲减通过m6A-YTHDC2介导的AMIGO2调控抑制RA-FLS活化

类风湿性关节炎&#xff08;RA&#xff09;是一种自身免疫性关节疾病&#xff0c;其特征是慢性关节滑膜炎、滑膜增生过度和关节损伤。近年来&#xff0c;N6-甲基腺苷&#xff08;m6A&#xff09;修饰的RNA在癌症和自身免疫疾病&#xff08;包括RA&#xff09;中的调控作用受到广…