319. 灯泡开关

初始时有 n 个灯泡关闭。
第 1 轮,你打开所有的灯泡。
第 2 轮,每两个灯泡你关闭一次。
第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。
第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。
找出 n 轮后有多少个亮着的灯泡。

示例 1:
输入:n = 3
输出:1
解释:
初始时, 灯泡状态 [关闭, 关闭, 关闭].
第一轮后, 灯泡状态 [开启, 开启, 开启].
第二轮后, 灯泡状态 [开启, 关闭, 开启].
第三轮后, 灯泡状态 [开启, 关闭, 关闭].
你应该返回 1,因为只有一个灯泡还亮着。

示例 2:
输入:n = 0
输出:0

示例 3:
输入:n = 1
输出:1

提示:
0 <= n <= 109
复制代码

解题

fun _0319_bulbSwitch() {
println("--------_0319_bulbSwitch-------")
println(bulbSwitch(3))
println(bulbSwitch(2))
println(bulbSwitch(1))
println(bulbSwitch(0))
}

fun bulbSwitch(n: Int): Int {
if (n == 1)
return 1
var result = 1
while (true) {
if (result * result > n)
break
result++
}
return result - 1
}
复制代码

672. 灯泡开关 Ⅱ

现有一个房间,墙上挂有 n 只已经打开的灯泡和 4 个按钮。
在进行了 m 次未知操作后,你需要返回这 n 只灯泡可能有多少种不同的状态。
假设这 n 只灯泡被编号为 [1, 2, 3 ..., n],这 4 个按钮的功能如下:
将所有灯泡的状态反转(即开变为关,关变为开)
将编号为偶数的灯泡的状态反转
将编号为奇数的灯泡的状态反转
将编号为 3k+1 的灯泡的状态反转(k = 0, 1, 2, ...)

示例 1:
输入: n = 1, m = 1.
输出: 2
说明: 状态为: [开], [关]

示例 2:
输入: n = 2, m = 1.
输出: 3
说明: 状态为: [开, 关], [关, 开], [关, 关]

示例 3:
输入: n = 3, m = 1.
输出: 4
说明: 状态为: [关, 开, 关], [开, 关, 开], [关, 关, 关], [关, 开, 开].

注意: n 和 m 都属于 [0, 1000].
复制代码

解题

fun _0672_flipLights() {
println("--------_0672_flipLights-------")
println(flipLights(1, 1))
println(flipLights(2, 1))
println(flipLights(3, 1))
}

/**
因为前 6 个灯唯一地决定了其余的灯。
这是因为修改第 xx 灯光的每个操作都会修改 第 (x+6)(x+6) 灯光,
因此 xx 灯光始终等于 (x+6)(x+6) 灯光。
实际上,前 3 个灯唯一地确定了序列的其余部分
*/
fun flipLights(n: Int, m: Int): Int {
val n = Math.min(n, 3)
if (m == 0) return 1
if (m == 1) return if (n == 1) 2 else if (n == 2) 3 else 4
if (m == 2) return if (n == 1) 2 else if (n == 2) 4 else 7
return if (n == 1) 2 else if (n == 2) 4 else 8
}
复制代码

1375. 灯泡开关 III

房间中有 n 枚灯泡,编号从 1 到 n,自左向右排成一排。最初,所有的灯都是关着的。
在 k 时刻( k 的取值范围是 0 到 n - 1),我们打开 light[k] 这个灯。
灯的颜色要想 变成蓝色 就必须同时满足下面两个条件:
灯处于打开状态。
排在它之前(左侧)的所有灯也都处于打开状态。
请返回能够让 所有开着的 灯都 变成蓝色 的时刻 数目 。

示例 1:
输入:light = [2,1,3,5,4]
输出:3
解释:所有开着的灯都变蓝的时刻分别是 1,2 和 4 。

示例 2:
输入:light = [3,2,4,1,5]
输出:2
解释:所有开着的灯都变蓝的时刻分别是 3 和 4(index-0)。

示例 3:
输入:light = [4,1,2,3]
输出:1
解释:所有开着的灯都变蓝的时刻是 3(index-0)。
第 4 个灯在时刻 3 变蓝。

示例 4:
输入:light = [2,1,4,3,6,5]
输出:3

示例 5:
输入:light = [1,2,3,4,5,6]
输出:6

提示:
n == light.length
1 <= n <= 5 * 10^4
light 是 [1, 2, ..., n] 的一个排列。
复制代码

解题

fun _1375_numTimesAllBlue() {
println("--------_1375_numTimesAllBlue-------")
println(numTimesAllBlue(intArrayOf(2, 1, 3, 5, 4)))
println(numTimesAllBlue(intArrayOf(3, 2, 4, 1, 5)))
println(numTimesAllBlue(intArrayOf(4, 1, 2, 3)))
println(numTimesAllBlue(intArrayOf(2, 1, 4, 3, 6, 5)))
println(numTimesAllBlue(intArrayOf(1, 2, 3, 4, 5, 6)))
}

fun numTimesAllBlue(light: IntArray): Int {
var result = 0
var curMax = 0
for (i in light.indices) {
curMax = Math.max(curMax, light[i])
if (curMax == i + 1)
result++
}
return result
}
复制代码

1529. 灯泡开关 IV

房间中有 n 个灯泡,编号从 0 到 n-1 ,自左向右排成一行。最开始的时候,所有的灯泡都是 关 着的。
请你设法使得灯泡的开关状态和 target 描述的状态一致,其中 target[i] 等于 1 第 i 个灯泡是开着的,等于 0 意味着第 i 个灯是关着的。
有一个开关可以用于翻转灯泡的状态,翻转操作定义如下:
选择当前配置下的任意一个灯泡(下标为 i )
翻转下标从 i 到 n-1 的每个灯泡
翻转时,如果灯泡的状态为 0 就变为 1,为 1 就变为 0 。
返回达成 target 描述的状态所需的 最少 翻转次数。

示例 1:
输入:target = "10111"
输出:3
解释:初始配置 "00000".
从第 3 个灯泡(下标为 2)开始翻转 "00000" -> "00111"
从第 1 个灯泡(下标为 0)开始翻转 "00111" -> "11000"
从第 2 个灯泡(下标为 1)开始翻转 "11000" -> "10111"
至少需要翻转 3 次才能达成 target 描述的状态

示例 2:
输入:target = "101"
输出:3
解释:"000" -> "111" -> "100" -> "101".

示例 3:
输入:target = "00000"
输出:0

示例 4:
输入:target = "001011101"
输出:5

提示:
1 <= target.length <= 10^5
target[i] == '0' 或者 target[i] == '1'
复制代码

解题

fun _1529_minFlips() {
println("--------_1529_minFlips-------")
println(minFlips("10111"))
println(minFlips("101"))
println(minFlips("00000"))
println(minFlips("001011101"))
}

fun minFlips(target: String): Int {
var target = "0$target"
var res = 0
for (i in 1 until target.length)
if (target[i] != target[i - 1]) ++res
return res
}
复制代码

683. K 个关闭的灯泡

N 个灯泡排成一行,编号从 1 到 N 。
最初,所有灯泡都关闭。每天只打开一个灯泡,直到 N 天后所有灯泡都打开。
给你一个长度为 N 的灯泡数组 blubs ,其中 bulls[i] = x 意味着在第 (i+1) 天,
我们会把在位置 x 的灯泡打开,其中 i 从 0 开始,x 从 1 开始。
给你一个整数 K ,请你输出在第几天恰好有两个打开的灯泡,
使得它们中间 正好 有 K 个灯泡且这些灯泡 全部是关闭的 。
如果不存在这种情况,返回 -1 。如果有多天都出现这种情况,请返回 最小的天数 。
复制代码

解题

fun _0683_kEmptySlots() {
println("--------_0683_kEmptySlots-------")
println(kEmptySlots(intArrayOf(1,3,2),1))// 2
println(kEmptySlots(intArrayOf(1,2,3),1))//-1
}
fun kEmptySlots(flowers: IntArray, k: Int): Int {
val n = flowers.size
if (n == 1 && k == 0) {
return 1
}
val sort: TreeSet<Int> = TreeSet()
for (i in 0 until n) {
sort.add(flowers[i])
val min = sort.lower(flowers[i])
val max = sort.higher(flowers[i])
if (min != null && flowers[i] - min == k + 1) {
return i + 1
}
if (max != null && max - flowers[i] == k + 1) {
return i + 1
}
}
return -1
}
复制代码

我是今阳,如果想要进阶和了解更多的干货,欢迎关注微信公众号 “今阳说” 接收我的最新文章