Golang每日一练(leetDay0108) 灯泡开关I\II Bulb Switcher

文章介绍了两个与灯泡开关相关的编程问题,319.灯泡开关BulbSwitcher和672.灯泡开关IIBulbSwitcherii,分别给出了用不同编程语言实现的解决方案,并指出第一个问题可以通过数学公式直接求解。此外,文章还提到了每日一练的编程栏目,涵盖多种编程语言的学习资源。

 

目录

319. 灯泡开关 Bulb Switcher  🌟🌟

672. 灯泡开关II Bulb Switcher ii  🌟🌟

🌟 每日一练刷题专栏 🌟

Rust每日一练 专栏

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


319. 灯泡开关 Bulb Switcher

初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。

第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换第 i 个灯泡的开关。直到第 n 轮,你只需要切换最后一个灯泡的开关。

找出并返回 n 轮后有多少个亮着的灯泡。

示例 1:

输入:n = 3
输出:1 
解释:
初始时, 灯泡状态 [关闭, 关闭, 关闭].
第一轮后, 灯泡状态 [开启, 开启, 开启].
第二轮后, 灯泡状态 [开启, 关闭, 开启].
第三轮后, 灯泡状态 [开启, 关闭, 关闭]. 

你应该返回 1,因为只有一个灯泡还亮着。

示例 2:

输入:n = 0
输出:0

示例 3:

输入:n = 1
输出:

提示:

  • 0 <= n <= 10^9

代码:

package main

import "fmt"

func bulbSwitch(n int) int {
	bulbs := make([]bool, n)
	for i := 0; i < n; i++ {
		for j := i; j < n; j += i + 1 {
			bulbs[j] = !bulbs[j]
		}
	}
	count := 0
	for _, b := range bulbs {
		if b {
			count++
		}
	}
	return count
}

func main() {
	fmt.Println(bulbSwitch(3))
	fmt.Println(bulbSwitch(0))
	fmt.Println(bulbSwitch(1))
}

输出:

1
0
1

其实本题只用一个公式就能解决:

```golang
func bulbSwitch(n int) int {
       return int(math.Sqrt(float64(n)))
}
```


672. 灯泡开关II Bulb Switcher ii

现有一个房间,墙上挂有 n 只已经打开的灯泡和 4 个按钮。在进行了 m 次未知操作后,你需要返回这 n 只灯泡可能有多少种不同的状态。

假设这 n 只灯泡被编号为 [1, 2, 3 ..., n],这 4 个按钮的功能如下:

  1. 将所有灯泡的状态反转(即开变为关,关变为开)
  2. 将编号为偶数的灯泡的状态反转
  3. 将编号为奇数的灯泡的状态反转
  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].

代码:

package main

import "fmt"

func flipLights(n int, m int) int {
	init := make([]int, n)
	for i := range init {
		init[i] = 1
	}
	ops := make([][2]int, 4)
	ops[0] = [2]int{0, 1} // toggle all
	ops[1] = [2]int{1, 2} // toggle even
	ops[2] = [2]int{0, 2} // toggle odd
	ops[3] = [2]int{2, 2} // toggle every 3
	count := make(map[string]bool)
	count[serialize(init)] = true
	for i := 0; i < m; i++ {
		for j, op := range ops {
			if i == 0 && j == 0 {
				// first operation: toggle all
				for k := range init {
					init[k] ^= op[0]
				}
			} else {
				// other operations
				for k := op[0]; k < n; k += op[1] {
					init[k] ^= 1
				}
			}
			count[serialize(init)] = true
		}
	}
	return len(count)
}

func serialize(arr []int) string {
	res := make([]byte, len(arr))
	for i, v := range arr {
		if v == 0 {
			res[i] = '0'
		} else {
			res[i] = '1'
		}
	}
	return string(res)
}

func main() {
	fmt.Println(flipLights(1, 1))
	fmt.Println(flipLights(2, 1))
	fmt.Println(flipLights(3, 1))
}

输出:

2
3
4


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.youkuaiyun.com/ 

Rust每日一练 专栏

(2023.5.16~)更新中...

Golang每日一练 专栏

(2023.3.11~)更新中...

Python每日一练 专栏

(2023.2.18~2023.5.18)暂停更

C/C++每日一练 专栏

(2023.2.18~2023.5.18)暂停更

Java每日一练 专栏

(2023.3.11~2023.5.18)暂停更

评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hann Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值