博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Microsoft 面试题 | 我能赢
阅读量:5844 次
发布时间:2019-06-18

本文共 1705 字,大约阅读时间需要 5 分钟。

专栏 | 九章算法

网址 | http://www.jiuzhang.com

1 题目描述

有两个人玩一个游戏,给定一个最大可取整数 maxChoosableInteger,两个人轮流从1~maxChoosableInteger 中取一个数,取过的数不可再取,若其中一方取过以后,

所有取过的数加起来的和大于等于desiredTotal,那么这个人获胜。

现在给你maxChoosableInteger和desiredTotal,问先手是否必胜,假定游戏双方均采取最优策略。

你可以假定给出的 maxChoosableInteger不超过20,desiredTotal不超过300。

样例

输入 :

maxChoosableInteger = 10 desiredTotal = 11

输出 :

false

样例说明

无论先手怎么取数,先手都会输掉游戏。

先手可以取1到10中的任何一个。如果先手取1,那么后手可以取2到10中的任何一个。

后手如果取10,那么就可以赢得游戏,因为此时和为1+10=11=desiredTotal。

假如先手取其他的数,那么后手仍然能赢得游戏,只要使和大于等于11即可。

2 解题思路

1

我们读完题发现这题似乎是一题经典的博弈问题,但是有一个很重要的限制条件————每个数只能取一次。

有了这个条件,我们很容易就能想到所有的取数方案,最多有 maxChoosableInteger! 种,即 1~maxChoosableInteger 的全排列。

但是一一枚举这maxChoosableInteger!种方案明显超过了能承受的时间复杂度。

2

经过对这maxChoosableInteger!种方案的思考,我们可以发现,

虽然方案有阶乘的数量级,但是这么多方案有很多的部分重复计算了,

类似前缀和的思想,我们计算1~n的前缀和,只要计算出1~n-1的前缀和再加上n即可,避免了多余的计算。

这里我们同样可以把之前计算的结果保留下来以方便之后的计算,我们称之为 记忆化搜索 ,和前缀和不同的是,这里用的是自顶向下(类似于分治的把大问题拆分为小问题的求解方法)的求解方法。

3

在记忆化搜索中,使用了两个条件判断胜利,

一是当前剩下的desiredTotal(减去了取走的数)小于等于0,

二是对于剩下的还未取的数,已经搜索过且是必胜的状态,

假如这个状态没有搜索过,就进行dfs判断这个状态,直到遇到判断过的状态或desiredTotal小于等于0。

其实本题也可以用自下而上的动态规划实现,状态表示和记忆化搜索相同。

4

对于记录状态的数组,

我们使用01向量表示,0代表这个数没有使用过,1代表已经使用过。

把1~maxChoosableInteger的使用情况定义为一个只有0,1的向量,

比如maxChoosableInteger=3,他们的使用情况有8种,分别是000(没有元素被使用),001,010,100,011,110,101,111(所有元素都被使用)。

再把这个向量转化成十进制数作为下标。

5

设maxChoosableInteger为n,

除了特殊情况外我们需要计算所有的状态,且每个状态只需要计算一次,则时间和空间复杂度均为O(2^n)。

3 参考代码

4 面试官角度

本题运用了记忆化搜索的方法,

能用记忆化搜索解出的能获得hire的评价,

如果能把状态压缩为一个十进制数,则能获得strong hire的评价。

5 Lintcode相关题目

不同的二叉查找树 http://www.lintcode.com/zh-cn/problem/unique-binary-search-trees/

交叉字符串 http://www.lintcode.com/zh-cn/problem/interleaving-string/

6 九章参考答案

http://www.jiuzhang.com/solution/can-i-win/

欢迎关注我的微信公众号:九章算法(ninechapter)。
精英程序员交流社区,定期发布面试题、面试技巧、求职信息等

转载地址:http://zjqcx.baihongyu.com/

你可能感兴趣的文章
Spring Cloud Config服务器
查看>>
commonservice-config配置服务搭建
查看>>
连接池的意义及阿里Druid
查看>>
ComponentOne 2019V1火热来袭!全面支持 Visual Studio 2019——亮点之WinForm篇
查看>>
全面的Spring Boot配置文件详解
查看>>
如何优雅地玩转分库分表
查看>>
Python递归函数与匿名函数
查看>>
我的友情链接
查看>>
CentOS添加永久静态路由
查看>>
mysql多实例的安装以及主从复制配置
查看>>
loadrunner安装运行一步一步来(多图)
查看>>
git请求报错 401
查看>>
动态追踪技术(四):基于 Linux bcc/BPF 实现 Go 程序动态追踪
查看>>
Cyber-Security: Linux 容器安全的十重境界
查看>>
监控工具htop的安装及使用
查看>>
Nodejs使用图灵机器人获取笑话
查看>>
【读书笔记】第三章 大型网站核心架构要素
查看>>
jvm参数设置
查看>>
易宝典文章——玩转Office 365中的Exchange Online服务 之十三 怎样管理Exchange Online的邮件用户和联系人...
查看>>
nexus 从Window迁移至Linux
查看>>