LeetCode:1997. 访问完所有房间的第一天(DP Java)

2024-03-30 16:12

本文主要是介绍LeetCode:1997. 访问完所有房间的第一天(DP Java),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1997. 访问完所有房间的第一天

题目描述:

实现代码与解析:

DP

原理思路:


1997. 访问完所有房间的第一天

题目描述:

你需要访问 n 个房间,房间从 0 到 n - 1 编号。同时,每一天都有一个日期编号,从 0 开始,依天数递增。你每天都会访问一个房间。

最开始的第 0 天,你访问 0 号房间。给你一个长度为 n 且 下标从 0 开始 的数组 nextVisit 。在接下来的几天中,你访问房间的 次序 将根据下面的 规则 决定:

  • 假设某一天,你访问 i 号房间。
  • 如果算上本次访问,访问 i 号房间的次数为 奇数 ,那么 第二天 需要访问 nextVisit[i] 所指定的房间,其中 0 <= nextVisit[i] <= i 。
  • 如果算上本次访问,访问 i 号房间的次数为 偶数 ,那么 第二天 需要访问 (i + 1) mod n 号房间。

请返回你访问完所有房间的第一天的日期编号。题目数据保证总是存在这样的一天。由于答案可能很大,返回对 109 + 7 取余后的结果。

示例 1:

输入:nextVisit = [0,0]
输出:2
解释:
- 第 0 天,你访问房间 0 。访问 0 号房间的总次数为 1 ,次数为奇数。下一天你需要访问房间的编号是 nextVisit[0] = 0
- 第 1 天,你访问房间 0 。访问 0 号房间的总次数为 2 ,次数为偶数。下一天你需要访问房间的编号是 (0 + 1) mod 2 = 1
- 第 2 天,你访问房间 1 。这是你第一次完成访问所有房间的那天。

示例 2:

输入:nextVisit = [0,0,2]
输出:6
解释:
你每天访问房间的次序是 [0,0,1,0,0,1,2,...] 。
第 6 天是你访问完所有房间的第一天。

示例 3:

输入:nextVisit = [0,1,2,0]
输出:6
解释:
你每天访问房间的次序是 [0,0,1,1,2,2,3,...] 。
第 6 天是你访问完所有房间的第一天。

提示:

  • n == nextVisit.length
  • 2 <= n <= 105
  • 0 <= nextVisit[i] <= i

实现代码与解析:

DP

class Solution {public int firstDayBeenInAllRooms(int[] nextVisit) {int mod = 1000000007;int n = nextVisit.length;long[] f = new long[n];f[0] = 0; // 第一次到达idx0是0,当开始读数据回退的时候才算第一天,所以这里是第0天for (int i = 1; i < n; i++) {int t = nextVisit[i - 1];f[i] = (f[i - 1] + 1 + f[i - 1] - f[t] + 1 + mod) % mod;}return (int)f[n - 1];}
}

原理思路:

        这题,我只能说看着短,但是这题真难想其实,尤其是哪个官解,写的更是让看不懂的更晕了。

        这里的dp[i]数组含义,第一次到第i间房间的天数。 

        所以答案是确定dp[n - 1]。

最主要的是递推式怎么写?

        房间只有偶数次访问才能向前走,所以,当到了第 i 间房间,说明前面的房间一定全部已经访问了偶数次,不然到不了这个房间。(为了书写方便,我用 v 代表nextVisit数组)

        第一次到达i - 1的房间时,一定会消耗一天回溯到  v[ i - 1] 的房间, 令v[i - 1] 为 t(方便书写),因为 i - 1之前的房间一定被访问了偶数次,所以v回溯到 t 房间一定是对其的奇数次访问,在这一时刻,t之前的房间一定也是偶数次访问,t 到 i - 1之间的房间也是偶数次访问,所以我们可以看作为第一次到达 t 房间的状态,我愿称之为重置(但以不是最初的时间,只是状态一致),所以直接用 f[ t ] 表示第一次到达t房间的天数进行后面的计算。

        这时想要第二次到达i - 1这个房间,就需要重新走一遍已经走过的路,用f[ i - 1] - f[ t ] ,即可表示走这段路花费的时间。这时第二次(偶次)到达了i - 1这个房间,再消耗一天,便到了 i 房间。

        这就是递推式f[ i ] 的由来。  f[ i ] = f[i - 1] + 1 + f[i - 1] - f[t] + 1;//注意我两个+1对应粗体字

        我愿称之为,虽然我每接近你一步,轮回的次数就会变多,但是我任然想不断的靠近你,即使每次回溯我都要再花费更长的时间重复经历一遍又一遍。

小细节:

        开long。

        取mod后f[ i - 1] 可能 小于 f [ t ] 所以先 + mod 再 % mod,防止负数出现。

这篇关于LeetCode:1997. 访问完所有房间的第一天(DP Java)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/861950

相关文章

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Java中Scanner的用法示例小结

《Java中Scanner的用法示例小结》有时候我们在编写代码的时候可能会使用输入和输出,那Java也有自己的输入和输出,今天我们来探究一下,对JavaScanner用法相关知识感兴趣的朋友一起看看吧... 目录前言一 输出二 输入Scanner的使用多组输入三 综合练习:猜数字游戏猜数字前言有时候我们在

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构

java解析jwt中的payload的用法

《java解析jwt中的payload的用法》:本文主要介绍java解析jwt中的payload的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解析jwt中的payload1. 使用 jjwt 库步骤 1:添加依赖步骤 2:解析 JWT2. 使用 N

springboot项目如何开启https服务

《springboot项目如何开启https服务》:本文主要介绍springboot项目如何开启https服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录springboot项目开启https服务1. 生成SSL证书密钥库使用keytool生成自签名证书将

Java实现优雅日期处理的方案详解

《Java实现优雅日期处理的方案详解》在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间,下面我们就来看看如何使用java处理这样的日期问题吧,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言一、日期的坑1.1 日期格式化陷阱1.2 时区转换二、优雅方案的进阶之路2.1 线程安全重构2