leetcode 464. 我能赢吗 官方代码的一步步演进

news2024/10/7 18:31:34

这里写自定义目录标题

  • 题目
  • 示例
  • 解题
    • 优化1 记忆化搜索
    • 优化2:使用二进制代替choosable_list
  • 计算复杂性

题目

在 “100 game” 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和 达到或超过 100 的玩家,即为胜者。如果我们将游戏规则改为 “玩家 不能 重复使用整数” 呢?
例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。
给定两个整数 maxChoosableInteger (整数池中可选择的最大数)和 desiredTotal(累计和),若先出手的玩家是否能稳赢则返回 true ,否则返回 false 。假设两位玩家游戏时都表现 最佳 。

示例

  • 输入:maxChoosableInteger = 10, desiredTotal = 11
  • 输出:false
  • 解释:无论第一个玩家选择哪个整数,他都会失败。第一个玩家可以选择从 1 到 10 的整数。如果第一个玩家选择 1,那么第二个玩家只能选择从 2 到 10 的整数。第二个玩家可以通过选择整数 10(那么累积和为 11 >= desiredTotal),从而取得胜利.同样地,第一个玩家选择任意其他整数,第二个玩家都会赢。

解题

该题目是给定一个从1到maxChoosableInteger的公共数据池,两个玩家轮流从数据池中选择数据构建一新的已选择数据池。如果某个玩家选择了一个数使已选择数据池的所有数据之和大于等于desiredTotal则该玩家赢了。该题的问题是判断先手玩家是否稳赢。

以maxChoosableInteger = 10, desiredTotal = 11为例说明算法的大体执行过程。首先,如下图,公共数据池是从1到10的数据,初始已选数据池为空。先手玩家A开始选择数据。首先碰到的一个问题就是玩家如何从公共数据池选择数据。因为这是一个博弈的问题,玩家是希望选择一个让自己稳赢的方案。

在这里插入图片描述
玩家A的选择方式没有特别好的方法只能逐个遍历公共数据池。比如玩家1选择了1之后,玩家A是否稳赢这个问题就变成了玩家B先手是否稳输,其实先手问题是相对的,这明显的一个递归问题。而显然玩家A选择了1之后 玩家B是稳赢的。

在这里插入图片描述

因此,这里很显示核心问题是一个递归函数,这个递归函数要解决的问题是基于当前状态先手玩家是否稳赢。

  • 输入:公共数据池,已选数据池
  • 输出:当前玩家是否能赢
  • 递归过程:终止条件是当前玩家从公共数据池中选择x,已选择数据池如果大于等于desiredTotal,则返回True即当前玩家赢了。否则需要递归判断在当前玩家选择了X之后对方玩家一定输,则返回True,同样是当前玩家赢,否则对方玩家赢。

递归过程了解之后即可以写了一个初始代码:

class Solution:
    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
        #特殊情况判定,如果maxChoosableInteger对应的所有数之和小于desiredTotal则永远无法赢
        if (1+maxChoosableInteger)*maxChoosableInteger//2<desiredTotal:
            return False
        #递归函数表示当前玩家是否稳赢
        #输入:公共数据池choosable_list,已选数据池之和choosed_sum
        def dfs(choosable_list,choosed_sum):
            #遍历公共数据池中的数据
            for x in choosable_list:
                #如果选了x之后已选数据池之和大于desiredTotal
                if choosed_sum+x>=desiredTotal:
                    return True
                #备份一个choosable_list
                chose_copy=[item for item in choosable_list]
                chose_copy.remove(x)
                #当前玩家选择x之后,对手玩家是否稳赢的判断,如果稳输则当前玩家赢
                if not dfs(chose_copy,choosed_sum+x):
                    return True
            return False
        choosable_list=[i+1 for i in range(maxChoosableInteger)]
        return dfs(choosable_list,0)

但是该方法会超时。这主要是因为递归过程会有重复计算问题。

优化1 记忆化搜索

python中的关于记忆化搜索方法有一个非常方便的方法,可以直接在递归函数 之前使用@cache修饰器,非常方法,那么我们来看看否可行。

在这里插入图片描述
即不支持参数choosable_list的形式,那么我们需要考虑是否可以使用一个数据来代替这个list。

优化2:使用二进制代替choosable_list

为什么可以想到使用二进制数代替choosable_list来标记1到maxChoosableInteger可选的状态呢?

  • 1 因为 1 <= maxChoosableInteger <= 20,也就是不超过32位
  • 2 公共数据池中的数据是从1到maxChoosableInteger的连续数据,不重复。

这里是自写的代码,其实跟官方代码基本相同。

class Solution:
    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
        #特殊情况判定,如果maxChoosableInteger对应的所有数之和小于desiredTotal则永远无法赢
        if (1+maxChoosableInteger)*maxChoosableInteger//2<desiredTotal:
            return False
        @cache
        #dfs函数是当前可选择的数字,已选择的数字之和
        def dfs(state,choosed_sum):
            #遍历当前可选数字
            for x in range(maxChoosableInteger):
                #需要根据state确定x是否已使用
                if (1<<x)&state:
                    continue
                #如果选择X后sum大于desiredTotal
                if choosed_sum+x+1>=desiredTotal or not dfs((1<<x)|state,choosed_sum+x+1):
                    return True
            return False
        return dfs(0,0)

计算复杂性

  • 时间复杂性 O ( 2 n ∗ n ) O(2^n*n) O2nn n等于maxChoosableInteger,每个递归函数最多调用 2 n 2^n 2n次。
  • 空间复杂性 O ( 2 n ) O(2^n) O2n,因为搜索的状态有 O ( 2 n ) O(2^n) O2n

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

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

相关文章

Kafka - 09 Kafka副本 | Leader选举流程 | Follower故障 | Leader故障

文章目录1. 副本基本信息2. Leader选举流程3. Follower故障4. Leader故障1. 副本基本信息 1&#xff09;Kafka 副本作用&#xff1a;提高数据可靠性。 2&#xff09;Kafka 默认副本 1 个&#xff0c;生产环境一般配置为 2 个&#xff0c;保证数据可靠性&#xff1b;太多副本会…

深度学习网络模型——DenseNet模型详解与代码复现

深度学习网络模型——DenseNet模型详解与代码复现1、DenseNet概述2、DenseNet网络结构1、DenseNet中的DenseBlock模块2、DenseNet中的Transition模块3、DenseNet网络结构参数设置4、实验结果对比1、DenseNet概述 2、DenseNet网络结构 1、DenseNet中的DenseBlock模块 2、DenseNe…

内网穿透:针对小白的VSCode+云服务器+本地Ubuntu搭建GPU云服务器

前言 自己实验室的情况&#xff1a; 实验室拥有自己的GPU集群、工作站使用仅限于线下或者远程向日葵(不稳定、速度慢)拥有自己的廉价cpu轻量云服务器&#xff08;阿里云服务器(2G2*cpu)&#xff0c;大概40左右一年&#xff09; 平时出差、在宿舍等需要远程操作&#xff0c;向…

Python学习笔记-数字类型

目录 1. 数字类型 1.1 整型 1.2 浮点数 1.3 复数 1.4 布尔类型 2. 常用内置数值计算函数库 3. 随机数函数 本文记录python中的基本数字类型信息&#xff0c;以及一些其他的相关知识点。 1. 数字类型 python中用于标识数字或者数值的数据类型&#xff0c;主要有如下分类…

​鸽群卫星(Flock)​介绍

鸽群卫星&#xff08;Flock&#xff09;是美国Planet公司[1]研制的3U遥感立方体卫星星座&#xff0c;单颗卫星重约5kg&#xff0c;也被称为“鸽子”&#xff08;Dove&#xff09;。鸽群星座主要有两类轨道&#xff1a;空际空间站释放420km高、52度倾角轨道&#xff08;ISS&…

R语言基于决策树的银行信贷风险预警模型

引言 我国经济高速发展&#xff0c;个人信贷业务也随着快速发展&#xff0c;而个人信贷业务对提高内需&#xff0c;促进消费也有拉动作用。有正必有反&#xff0c;在个人信贷业务规模不断扩大的同时&#xff0c;信贷的违约等风险问题也日益突出&#xff0c;一定程度上制约着我…

力扣(LeetCode)115. 不同的子序列(C++)

动态规划 状态转移方程 f[i,j]{f[i−1,j]f[i−1,j]f[i−1,j−1]if s[i]t[j]f[i,j]\begin{cases} f[i-1,j]\\ f[i-1,j]f[i-1,j-1]&\text{if } s[i]t[j] \end{cases}f[i,j]{f[i−1,j]f[i−1,j]f[i−1,j−1]​if s[i]t[j]​ 无论选不选 s[i]s[i]s[i] &#xff0c; f[i][j]f[i…

解决报错:fatal: in unpopulated submodule *

目录 问题 解决 问题 今天想把两个 Git 工程合并成一个工程&#xff0c;尽管已经将其中一个工程的 .git 目录删除了&#xff0c;但是在合并提交时还是遇到了一个和子模块相关的报错&#xff0c;具体报错信息如下&#xff1a; fatal: in unpopulated submodule * 报错截图如下…

【iMessage苹果相册日历推位置推送】软件安装deviceToken是由APNs生成的

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

SpringBoot+html+vue模板开发

除了对某个表基本的增删改查以外&#xff0c;可能需要额外的增加操作&#xff0c;这里是通过按钮来实现的 1、新增一个测试按钮 <el-button type"primary" class"butT" click"test()">测试</el-button> 2、这个按钮绑定一个方法t…

Android 创建桌面组件Widget——构建应用微件(二)

Android 创建桌面组件Widget——构建应用微件&#xff08;二&#xff09;Android 创建桌面组件Widget——构建应用微件&#xff08;二&#xff09;概览使用 AppWidgetProvider 类接收应用微件广播 Intent固定应用微件设置预览图片完整代码Android 创建桌面组件Widget——构建应…

Spark学习(7)-SparkSQL函数定义

1 SparkSQL 定义UDF函数 目前在SparkSQL中&#xff0c;仅仅支持UDF和UDAF函数&#xff0c;python仅支持UDF。 1.1 定义方式 定义方式有两种&#xff1a; sparksession.udf.register() 注册的UDF可以用于DSL和SQL&#xff0c;返回值用于DSL风格&#xff0c;传参内的名字用于SQ…

如何在Odoo中添加水印?

为了防止信息的泄露&#xff0c;水印作为一种防泄密的方式&#xff0c;被使用的频率越来越高。 那么在Odoo中&#xff0c;如何添加水印呢&#xff1f;其实添加的方法有很多&#xff0c;如利用svg生成背景图&#xff0c;重复的dom元素覆盖等等。 本文主要讲解利用canvas输出背…

不懂单链表? 这篇文章就帮你搞明白

坚持看完&#xff0c;结尾有思维导图总结 链表对指针的操作要求不低链表的概念链表的特性链表的功能(最重要)定义和初始化头插头删细节说明尾插尾删寻找链表元素与打印链表在 某位置后插入删除在某位置的插入删除销毁链表链表的概念 什么是链表 官方概念&#xff1a;链表是一种…

链表(1)

我们以前学过的线性数据结构底层原理都是依托静态数组来实现的&#xff0c;今天我们讲学习一个最简单的动态数据结构---->链表&#xff01; 掌握链表有助于学习更加复杂的数据结构&#xff0c;例如&#xff1a;二叉树、trie 链表的优点是不需要处理固定的问题&#xff0c;…

mavon-editor的使用

vue3vitets下安装mavon-editor 3.0.0-beta版本&#xff0c;效果如下&#xff1a; 安装 //引入样式 import mavon-editor/dist/css/index.css; import mavonEditor from mavon-editor; app.use(router).use(mavonEditor).mount(#app);<template><div class"rich…

zabbix主动监控和被动监控

目录 一、环境准备 1、搭建zabbix基础环境 二、主动监控与被动监控介绍 三、设置客户端为主动监控 1、给web2主机安装zabbix_agent 2、修改主动监控配置 四、设置zabbix管理端主动监控 1、克隆模板 2、给目标主机绑定主动监控模板 3、查看主动监控的数据 一、环境准备…

【HIT-OSLAB-实验中的碎碎念】

文章目录应该养成的好习惯删除 替换 修改 内容时 记得留备份遇到问题要通过文字 图片 等多种途径去记录不同的项目应该在不同的文件夹进行处理代码文档 记得添加一些注释用于说明功能多输出有区别度的提示信息s找bug 先定位错误 再改当一份代码有不同版本的时候 记得说明每份代…

109376-05-8,Boc-QRR-AMC, Hepsin substrate

Boc-QRR-AMC是跨膜丝氨酸蛋白酶hepsin的底物&#xff0c;也用于测定酿酒酵母中的可辛(Kex2内蛋白酶)。Boc-QRR-AMC的库存解决方案最好在DMSO中准备。 编号: 187545中文名称: Hepsin substrate&#xff1a;Boc-Gln-Arg-Arg-7-氨基-4-甲基香豆素英文名: Boc-Gln-Arg-Arg-AMCCAS号…

全球No.1集装箱人工智能企业CIMCAI中集飞瞳,集装箱信息识别铅封号识别API免费,集装箱识别率99.98%高泛化性,全球两千+企业用户使用

全球No.1集装箱人工智能企业CIMCAI中集飞瞳&#xff0c;先进人工智能AI科技打造飞瞳引擎™AI集装箱检测云服务&#xff0c;集装箱信息识别铅封号识别API免费&#xff0c;集装箱识别率99.98%高泛化性&#xff0c;全球两千企业用户使用。CIMCAI中集飞瞳成熟港航人工智能核心技术及…