leetcode 375. 猜数字大小 II-【python3详细图解】递归+记忆化搜索与动态规划

news2024/11/26 9:00:00

题目

我们正在玩一个猜数游戏,游戏规则如下:
我从 1 到 n 之间选择一个数字。你来猜我选了哪个数字。如果你猜到正确的数字,就会 赢得游戏 。如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。每当你猜了数字x并且猜错了的时候,你需要支付金额为x的现金。如果你花光了钱,就会输掉游戏。给你一个特定的数字n,返回能够确保你获胜的最小现金数,不管我选择那个数字。

示例

在这里插入图片描述

  • 输入:n = 10
  • 输出:16

题解

这里还是首先人工找确定一个大体的过程。以上图示例进行说明,开始的时候一共有10个可选数据。比如选择1之后只有比1大的子序列从2到10,选择2序列被分成两个。接下现是对划分后的子序列继续执行相同的操作。可见这至少是一个递归过程。递归函数的目标是给定一个可选数据列,计算获胜的最小现金数。这个递归也与最终所求的问题一致。
在这里插入图片描述
那么我们来分析一下这个递归函数如何写。递归函数的输入只包含了一个数据列,这个数据列明显是1到n的一个子序列,因此,需要用两个变量确定该序列start,与end。dfs(start,end)表示[start,start+1,…,end]这个数据如果获胜需要支付的最小现金数。比如初始[1,…,10]数据列,猜x获胜有3种情况:

  • 猜对了,确实是x,那么需要支持0
  • 猜错,正确的数据比x小,这就转化成了求[1,…,x-1]这个数据列获胜需要支付的最小现金数。支付的现金数=x+dsf(1,x-1)。
  • 猜错,正确的数据比x大,这就转化成了求[x+1,…,n]这个数据列获胜需要支付的最小现金数。支付的现金数=x+dsf(x+1,n)。
    因此,要想获得胜利的话,需要取这三种情况的最大值。对于猜x中的x可以是从1到n的所有数。而x所有的可选择的数中需要选择最小的一个即可以得到获胜需要支付的最小现金数。
    递归方程可以写为:
    在这里插入图片描述
    最后,这道题目的边界有些特殊。
  • 1 i=j表示最后剩下一下数了,那一定能猜对,因此不需要支持现金所以为0;
  • 2 i=j-1,这种情况表示只剩下两个数,这里有两种选择。选择i的话,选对了不需要支持现金,选错了需要支持i。选择j的话选对了支持0,选错了支付j。这两种选择支个最小值,因此是i。
    到这里递归函数的整个过程就比较明显了。

递归函数:

  • 输入:数据列表
  • 输出:获胜的最小支付现金数
  • 过程:边界条件判定,递归过程。

代码

class Solution:
    def getMoneyAmount(self, n: int) -> int:
        #记忆化搜索
        @functools.lru_cache(maxsize=None)
        def dfs(start, end) :
            #边界条件
            if end-start <= 0 : return 0
            if end-start == 1 : return l
            #递归方程
            return min((i+max(sol(l,i-1), sol(i+1,r)) for i in range(l, r+1)))
        return sol(1,n)

整个过程还是比较简单的。比较好想到的。

动态规划

通常情况记忆化搜索+递归在能固定状态维度的情况下都能写成动态规划。但是这里相对需要注意的是动态规划状态方程的遍历顺序。
这里动态规划dp[i][j]表示的含义与前面的递归函数dfs是一样的,表示从i到j的数据列中想要获胜的最小支付现金数。这个根据前面的分析写下状态转移方程:
在这里插入图片描述
这里稍微有点绕人的地方就是边界问题。首先是j=i+1的情况需要确定。其次,遍历的时候k不能等于j,如果等于j的话就超出边界了。
首先,初始化dp状态矩阵如下图。
在这里插入图片描述
下面根据状态转移矩阵来尝试更新一下dp矩阵,先从左到右,从上到下更新。
第一步更新dp[1][1]。
在这里插入图片描述
第2步更新dp[1][2]。dp[1][2]不依赖于其他状态,直接根据j=i+1来更新。
在这里插入图片描述

接下来是关键更新dp[1][3],这里dp[1][3]根据公式依赖于dp[1][0],dp[1][3],dp[1][1],dp[2][3]。但是dp[2][3]现在是一个未更新状态。因此这遍历过程是从左到右,从下往上。
现在就可以写代码了。

递归代码:

class Solution:
    def getMoneyAmount(self, n: int) -> int:
        #特殊情况
        if n==1:
            return 0
        #dp初始化
        dp=[[0]*(n+1) for _ in range(n+1) ]
        #i从下往上 j从左到右
        for i in range(n-1,0,-1):
            for j in range(i+1,n+1):
                #状态转移方程中的j=i+1的情况
                if j-i==1:
                    dp[i][j]=i
                else:
                    #状态转移方程
                    dp[i][j]=min([k+max(dp[i][k-1],dp[k+1][j]) for k in range(i,j)])
        return dp[1][n]

计算复杂性

  • 时间复杂度: O ( n 3 ) O(n^3) O(n3),其中 n 是给输入的参数。为什么是 n 3 n^3 n3,可以看到代码中有i与j的两层for循环遍历最坏是 n 2 n^2 n2。但是在状态转移方程中也存在一个关于k的for循环遍历。因此。时间复杂度是 O ( n 3 ) O(n^3) O(n3)
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2),是dp状态矩阵占用的空间。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二十、JavaScript——逻辑非

! 逻辑非- &#xff01;可以对一个值进行非运算 - 它可以对一个布尔值进行取反操作 true 变成 false false 变成 true - 如果对一个非布尔值进行取反&#xff0c;它会将其先转换为布尔值&#xff0c;再进行取反操作 可以利用这个特点将其他类型转换为布尔值 <script>/*! …

Hybrid模式下,如何实现热更新?

做过开发的小伙伴应该对“热更新”不陌生吧&#xff01;热更新就是指在游戏或软件更新的时候&#xff0c;不用再重新下载安装包进行安装&#xff0c;而是在启动应用程序的时候&#xff0c;在内部进行资源或代码的更新。那么如今&#xff0c;市场为什么越来越多地选择热更新技术…

数据结构——图最全总结(期末复习必备)

目录 图 定义&#xff1a; 基本术语&#xff1a; 图的存储结构 邻接矩阵 邻接表 十字链表 邻接多重表 图的遍历 深度优先搜索(Depth First Search,DFS) 广度优先搜索(Breadth First Search,BFS) 图的应用 最小生成树 普利姆算法 克鲁斯卡尔算法 最短路径 单源最短…

优蓝冲刺港股:上半年期内亏损过亿 主打蓝领人才服务

雷递网 雷建平 12月14日优蓝国际控股股份有限公司&#xff08;简称&#xff1a;“优蓝”&#xff09;日前递交招股书&#xff0c;准备在香港上市。上半年期内亏损1.18亿优蓝是一家蓝领终身服务平台&#xff0c;旨在成为蓝领人才的首选终身服务平台。截至最后实际可行日期&#…

[附源码]Nodejs计算机毕业设计基于博客系统的UI手机界面展示Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

vue3插槽(匿名插槽-具名插槽-插槽作用域-动态插槽)

文章目录容器布局匿名插槽具名插槽作用域插槽动态插槽容器布局 &#x1f468;&#x1f3fb; parent.vue <script setup lang"ts"> import { ref, useAttrs, defineProps } from "vue"; import children from ./children.vue</script><tem…

界面控件DevExpress WinForm——HTML-CSS感知控件介绍

DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…

疫情防控|Springboot+小程序+校园疫情防控系统设计与实现

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

【刷题笔记】之牛客面试必刷TOP101(二分查找-I + 二维数组中的查找 + 寻找峰值 + 数组中的逆序对 + 旋转数组的最小数字 + 比较版本号)

目录 1. 二分查找-I 2. 二维数组中的查找 3. 寻找峰值 4. 数组中的逆序对 5. 旋转数组的最小数字 6. 比较版本号 1. 二分查找-I 题目链接&#xff1a;二分查找-I_牛客题霸_牛客网 (nowcoder.com) 题目要求&#xff1a; 上代码 import java.util.*;public class Solut…

Spring MVC学习 | 视图RESTFul

文章目录一、视图1.1 视图对象View1.2 ThymeleafView1.3 转发视图1.4 重定向视图1.5 视图控制器二、RESTFul2.1 简介2.2 PUT和DELETE请求的实现2.2.1 HiddenHttpMethodFilter过滤器2.2.2 实现PUT请求2.2.3 实现DELETE请求学习视频&#x1f3a5;&#xff1a;https://www.bilibil…

Python 元组(Tuple)操作详解

Python的元组与列表类似&#xff0c;不同之处在于元组的元素不能修改,元组使用小括号,列表使用方括号,元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可 一、创建元组 代码如下: 1 2 3 tup1 (physics, chemistry, 1997, 2000); tup2 (1, 2, 3, 4, 5 ); tup3 &qu…

Redis实现朋友圈,微博等Feed流功能,实现Feed流微服务(业务场景、实现思路和环境搭建)

文章目录业务场景Feed流相关概念Feed流特征Feed流分类实现思路环境搭建数据库表结构新建Feeds功能微服务ms-feeds配置类 RedisTemplateConfigurationREST配置类 RestTemplateConfigurationFeeds 实体类FeedsVO 响应类业务场景 在互联网领域&#xff0c;尤其现在的移动互联网时…

Linux环境下MySQL的安装与使用

目录 一&#xff1a;安装MYSQL说明 1.1 查看是否安装过MySQL 1.2 MYSQL的卸载 二&#xff1a;MySQL在Linux下的安装 三&#xff1a;MYSQL登录 3.1 首次登录 3.2 修改密码 3.3 设置远程登录 一&#xff1a;安装MYSQL说明 1.1 查看是否安装过MySQL 检查rpm安装包 rpm -…

JAVA毕业设计——基于ssm高校共享单车管理系统 (源代码+数据库)604

代码地址 https://github.com/ynwynw/webike-public 毕业设计所有选题地址 https://github.com/ynwynw/allProject 基于ssm高校共享单车管理系统 (源代码数据库)604 一、系统介绍 用户管理&#xff0c;服务点管理&#xff0c;单车管理&#xff0c;分类管理&#xff0c;学生管…

基于java+springboot+mybatis+vue+mysql的大学生体质测试管理系统

项目介绍 随着我国大学生数量的不断增加&#xff0c;个个高校对大学生的体质也开始高度的进行重视&#xff0c;只有拥有了高强健康体质的大学生才能够全身心的投入到学习和工作中&#xff0c;为了能够更好的对大学生的体质进行检测我们通过java编程语言&#xff0c;后端采用sp…

redis之哨兵机制

0. 前言 我们知道&#xff0c;只有主库才能有写操作&#xff0c;而从库只能进行读操作&#xff0c;那么当主库宕机后&#xff0c;如何保证服务的正常进行呢&#xff1f; 本文主要介绍的是 Redis 提供的哨兵机制&#xff0c;通过哨兵监控主库的状况&#xff0c;如果发现主库下…

Python迭代法Iteration的讲解及求解海藻问题、方程问题实战(超详细 附源码)

一、迭代法简介 迭代法&#xff08;iteration&#xff09;是现代计算机求解问题的一种基本形式。迭代法与其说是一种算法&#xff0c;更是一种思想&#xff0c;它不像传统数学解析方法那样一步到位得到精确解&#xff0c;而是步步为营&#xff0c;逐次推进&#xff0c;逐步接近…

[附源码]Python计算机毕业设计高校本科毕业及资料存档管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

十二、JavaScript——其他数据类型

布尔值 &#xff08;boolean&#xff09;- 布尔值主要用于进行逻辑判断 - 布尔值只有两个 true 和 false (不用加引号) 空指 (null) - 空值用来表示空对象 - 空指只有一个 NULL - 用typeof检查空值时返回object 未定义 &…

二面蚂蚁金服(交叉面),已拿offer,Java岗定级阿里P6

记一次蚂蚁金服Java程序员面试经历&#xff08;均为交叉面&#xff09; ​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 一面 自我介绍 项目中的监控&#xff1a;那个监控指标常见的有哪些&#xff1f; 微服务涉及到的技术以及需要…