leetcode957. N 天后的牢房
8 间牢房排成一排,每间牢房不是有人住就是空着。
每天,无论牢房是被占用或空置,都会根据以下规则进行更改:
- 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用。
- 否则,它就会被空置。
(请注意,由于监狱中的牢房排成一行,所以行中的第一个和最后一个房间无法有两个相邻的房间。)
我们用以下方式描述监狱的当前状态:如果第 i
间牢房被占用,则 cell[i]==1
,否则 cell[i]==0
。
根据监狱的初始状态,在 N
天后返回监狱的状况(和上述 N 种变化)。
--
思路:
如果是按照一般思路,根据前一天状态,更新第二天状态,逻辑会很清晰,但是会超时或溢出(当N=1000000000时),因为要生成N次数组来保存状态。
优化办法:
1、题干是8个房间,没个房间就0或1两种状态,所以8个房间最多一共也就 2的8次方 =256种状态,
2、状态是有限的,而 天数N可以是无穷大的,所以规律就在这256种之内。
3、最多生成256天的状态, 在这之内,不断寻找有无相同状态的一天,如果有,那么规律就出现了
1. 2. [3]. . . . k . . . . 256. . N
加入我们算出第k天的状态,和第3天一致,那么从k之后的未来所有状态,都是处于 3到k 之间循环的。
步骤:
1. 添加第0天状态到 list
2. 根据 list中的最后一天的状态pre,再添加新的一天的状态 cur
3. 查看cur 在list 0~pre中有无重复,如果有,规律出现,返回出现的下标index,如果无 继续上述步骤
4. (N-index)%(k-index) + index 即为结果的下标
- //957. N 天后的牢房
- public int[] prisonAfterNDays(int[] cells, int N) {
- if (N == 0) {
- return cells;
- }
- ArrayList<int[]> list = new ArrayList<>();
- list.add(cells);
- int k = 1; //k为第一天
- while (k <= N) {
- int[] cur = prisionStatus(list.get(k - 1));//根据昨天的状态获取今天的状态
- list.add(cur);//将今天的状态添加至list
- int index = findStatus(list);//循环判断list中是否存在已有状态,如果有返回下标,无返回-1
- if (index != -1) { //如果 index != -1 ,说明找到重复 , ps:此处存在 /by zero 异常
- try {
- int res = (N - index) % (k - index); //结果的下标
- return list.get(index + res);
- } catch (Exception e){
- return list.get(index); //存在异常的情况是 index + 1 == cur ,也就是昨天和今天状态一致,也意味着监狱状态稳定,以后不会变化。
- }
- }
- k++;
- }
- return list.get(list.size() - 1);
- }
- //根据昨天获取当天监狱状态
- private int[] prisionStatus(int[] pre) {
- int[] cur = new int[pre.length];
- cur[0] = 0;
- cur[cur.length - 1] = 0;
- for (int i = 1; i < pre.length - 1; i++) {
- if (pre[i - 1] == pre[i + 1]) {
- cur[i] = 1;
- } else {
- cur[i] = 0;
- }
- }
- return cur;
- }
- //循环判断list中是否存在已有状态,如果有返回下标,无 返回-1
- private int findStatus(ArrayList<int[]> list) {
- for (int i = 0; i <= list.size() - 2; i++) {
- if (arrayIsSame(list.get(list.size() - 1), list.get(i))) {
- return i;
- }
- }
- return -1;
- }
- //判断数组是否一致
- private boolean arrayIsSame(int[] a, int[] b) {
- if (a.length != b.length) {
- return false;
- }
- for (int i = 0; i < a.length; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
- }
leetcode957. N 天后的牢房的更多相关文章
- [Swift]LeetCode957. N天后的牢房 | Prison Cells After N Days
There are 8 prison cells in a row, and each cell is either occupied or vacant. Each day, whether the ...
- Leetcode 957.N天后的牢房
Leetcode 957.N天后的牢房 8间牢房排成一排,每间牢房不是有人住就是空着. 每天,无论牢房是被占用或空置,都会根据以下规则进行更改: 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该 ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- Leetcode题解 - 部分中等难度算法题解(56、957、825、781、1324、816)
957. N 天后的牢房 思路: 模拟变换,当N天结合后返回 => 当N非常大的时候,超时 => 一般N很大的时候,这种题目必然存在循环,所以记录找过的状态,一旦出现已经访问过的状态可立即 ...
- Tomcat shutdown执行后无法退出进程问题排查及解决
问题定位及排查 上周无意中调试程序在Linux上ps -ef|grep tomcat发现有许多tomcat的进程,当时因为没有影响系统运行就没当回事.而且我内心总觉得这可能是tomcat像nginx一 ...
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
- iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法
问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...
- Hyper-V 激活Windows系统重启后黑屏的解决方法 + 激活方法
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...
- js获取给定月份的N个月后的日期
1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...
随机推荐
- Zookeeper(二)数据模型
Zookeeper数据模型ZNode 问题 ZK的数据模型ZNodes是什么样的: 树形结构,每个叶子节点都存储着数据,且可挂载子节点: 路径作为叶子节点名称,数据作为叶子节点内的数据: Znode可 ...
- EBS 清除高速缓存
以R12.1.3为例: 以 “功能管理员 ”职责打开OAF界面 然后依次点击“核心服务”->“高速缓存结构”->“全局配置”->“清除所有高速缓存”->“是”,即可
- Dubbo Admin 控制台
下载项目源码 https://github.com/apache/incubator-dubbo-admin 解压后配置 zookeeper 地址,路径为 dubbo-admin-server/src ...
- shell编程常用命令
Linux中常用的命令 #nl filename 使用nl命令打印文件内容并显示行号 #sed '/nw/,$d' filename 使用sed命令删除匹配nw至最后一行的内容 ...
- Detected memory leaks! 解决方法
Detected memory leaks!Dumping objects ->f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occmgr.cpp(195) ...
- leetcode -1 count the path
- 浏览器端-W3School-JavaScript:JavaScript Math 对象
ylbtech-浏览器端-W3School-JavaScript:JavaScript Math 对象 1.返回顶部 1. Math 对象 Math 对象用于执行数学任务. 使用 Math 的属性和方 ...
- JavaWeb实现文件上传下载功能实例解析 (好用)
转: JavaWeb实现文件上传下载功能实例解析 转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web ...
- fiddler抓取app的https的包
线上问题的排查有时候需要抓包,但是是https协议的,则需要安装证书 在Android 6.0 (API level 23)及以前,APP默认信任系统自带的CA证书以及用于导入的CA证书,Androi ...
- 我们公司的delphi代码(胆不是我写的!),看看,你觉得怎么样
unit unt_LotBill_dyc; interface uses windows, SysUtils, Classes, ComCtrls, Forms, Controls, StrUtils ...