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 天后的牢房的更多相关文章

  1. [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 ...

  2. Leetcode 957.N天后的牢房

    Leetcode 957.N天后的牢房 8间牢房排成一排,每间牢房不是有人住就是空着. 每天,无论牢房是被占用或空置,都会根据以下规则进行更改: 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该 ...

  3. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  4. Leetcode题解 - 部分中等难度算法题解(56、957、825、781、1324、816)

    957. N 天后的牢房 思路: 模拟变换,当N天结合后返回 => 当N非常大的时候,超时 => 一般N很大的时候,这种题目必然存在循环,所以记录找过的状态,一旦出现已经访问过的状态可立即 ...

  5. Tomcat shutdown执行后无法退出进程问题排查及解决

    问题定位及排查 上周无意中调试程序在Linux上ps -ef|grep tomcat发现有许多tomcat的进程,当时因为没有影响系统运行就没当回事.而且我内心总觉得这可能是tomcat像nginx一 ...

  6. XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法

            在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...

  7. iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法

    问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...

  8. Hyper-V 激活Windows系统重启后黑屏的解决方法 + 激活方法

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  9. js获取给定月份的N个月后的日期

    1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...

随机推荐

  1. Miniui 表单验证

    自定义表单验证: input输入框的表单验证可通过vtype和onvalidation事件两种方式实现 可编辑列表(例如div)的表单验证只能通过vtye来实现表单验证 (1)vtype方式: jsp ...

  2. 套接字之sendmsg系统调用

    sendmsg系统调用允许在用户空间构造消息头和控制信息,用此函数可以发送多个数据缓冲区的数据,并支持控制信息:当调用进入内核后,会将用户端的user_msghdr对应拷贝到内核的msghdr中,然后 ...

  3. DS博客作业--课程总结

    1.当初你是如何做出选择计算机专业的决定的? 经过一年学习,你的看法改变了么,为什么? 你觉得计算机是你喜欢的领域吗,它是你擅长的领域吗? 为什么? 刚开始填报志愿的时候,因为我个人是没有什么比较特别 ...

  4. java 方法的重载重写

    面向对象有三大特性:封装,继承,多态 多态则需要满足三大条件1要有继承2要有重写3父类引用子类对象 很多人对方法的重载重写有很大疑问,下面我来介绍一下方法的重载重写 方法重载就是方法名称重复,加载参数 ...

  5. centos7 apache php git pull

    mkdir /usr/share/httpd/.ssh cp /root/.ssh/* /usr/share/httpd/.ssh chown -R apache:apache /usr/share/ ...

  6. Dark 运算符

    1 赋值运算符 ??= b ??= "hello" 若b为空,则把"hello"赋给b . 2 三目运算符 boolean ? expression1 : ex ...

  7. CompletableFuture用法介绍

    一.CompletableFuture用法入门介绍 入门介绍的一个例子: package com.cy.java8; import java.util.Random; import java.util ...

  8. [Cinder] 存储 Qos

    目录 文章目录 目录 前言 操作步骤 参考文章 前言 Cinder 支持 front-end 和 back-end 两种类型的存储 QoS,前者由 Hypervisor 端实现(e.g. 通过 Lib ...

  9. 进程管理工具之supervisor[安装并使用]

    在Linux服务器中,有时候我们需要一个进程需要可靠的在后台运行,并且能够监控进程状态,在意外结束时能够自动重启等.此时就可以使用supervisor. supervisor 是使用Python开发的 ...

  10. 替换RTXLogo插件说明

    一.包含Logo图标文件介绍 (一)桌面图标包含在RTX.exe (二)桌面右下角图标包含在MainFrameRes.dll (三)RTX设置图标包含在Config.dll (四)查看用户信息图标包含 ...