leetcode(力扣) 319. 灯泡开关 (暴力模拟) (数学推论)

题目在这:https://leetcode-cn.com/problems/bulb-switcher/

法一(暴力):

这道题题目描述的就很清楚,由于第一轮和第二轮都是固定的,所以可以直接从第三轮开始,n如果等于0或者1,就直接返回0或者1。
从第三轮开始,N轮时,下标为N-1的灯变换开关。所以直接写两层for就行了。

完整代码

		if n == 0:
            return 0
        if n == 1:
            return 1
        # 初始 [关闭, 关闭,关闭, 关闭,]
        # 第一轮 [开启, 开启,开启,开启]
        # 第二轮 [开启, 关闭,开启,关闭]
        # 第三轮 [开启, 关闭,关闭, 关闭]
        # 第四轮 [开启,关闭,关闭,开启]
        # 先设置初始数组
        res = [True for i in range(n)]
        time = n
        for i in range(2, n+1):
            j = 1
            while i * j -1 < len(res):
                if res[i * j - 1]:
                    res[i * j - 1] = False
                    n -=1
                else:
                    res[i * j - 1] = True
                    n +=1
                # res[i * j - 1] = False if res[i * j - 1] else True
                j += 1
        return n

超时了。。。。。

法二(数学规律):

我们直接输出 n从0-999的时候每次等亮的个数。

0 轮亮着的灯数为 01 轮亮着的灯数为 12 轮亮着的灯数为 13 轮亮着的灯数为 14 轮亮着的灯数为 25 轮亮着的灯数为 26 轮亮着的灯数为 27 轮亮着的灯数为 28 轮亮着的灯数为 29 轮亮着的灯数为 310 轮亮着的灯数为 311 轮亮着的灯数为 312 轮亮着的灯数为 313 轮亮着的灯数为 314 轮亮着的灯数为 315 轮亮着的灯数为 316 轮亮着的灯数为 417 轮亮着的灯数为 418 轮亮着的灯数为 419 轮亮着的灯数为 420 轮亮着的灯数为 421 轮亮着的灯数为 422 轮亮着的灯数为 423 轮亮着的灯数为 424 轮亮着的灯数为 4

规律还是挺明显的,亮灯个数随着轮数的增加而增加。

从0轮开始:
3轮增加一个亮灯数,后面5轮增加一个,再后面 7轮增加一个亮灯数,再后面 9轮增加一个亮灯数,以此类推。
根据这个规律写程序。

完整代码

 if n == 0:
            return 0
        if n == 1:
            return 1
        res = 1
        i = 3
        j = 1
        while True:
            if  n <= i:
                return res
            j +=2
            i += j + 2
            res +=1

当然这道题的正经数学方法放到最后,但其实每次做到这种数学推论的题,并不是很简单就能想到,还是用这样旁门左道的方法比较容易解题。

正经推理:

  1. 每次某个灯被开关,是当前遍历的i为它的因子
  2. 某个灯被开关奇数次最后会亮着,偶数次最后会熄灭
  3. 某个数的因子个数为奇数个,它的所有质因子都出现了偶数次(完全平方数)
  4. 小于等于n的完全平方数个数为,1^2 … 2^2 … … sqrt(n) ^ 2, 即sqrt(n)

    leetcode(力扣) 319. 灯泡开关 (暴力模拟) (数学推论)_第1张图片
    完整代码:
class Solution:
    def bulbSwitch(self, n: int) -> int:
        return int(sqrt(n))

你可能感兴趣的:(个人笔记,交流学习,leetcode,python)