• 319. Bulb Switcher


    Problem statement:

    There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the ith round, you toggle every i bulb. For the nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds.

    Example:

    Given n = 3. 
    At first, the three bulbs are [off, off, off]. After first round, the three bulbs are [on, on, on]. After second round, the three bulbs are [on, off, on]. After third round, the three bulbs are [on, off, off].
    So you should return 1, because there is only one bulb is on.

    Analysis:

    For the solution, it is the most simple answer in leetcode I have ever seen, return sqrt(n), orz. But it is hard to figure it out.

    I can tell my story about how to solve this problem. Although is not smart as those top rated, I like this track to solve the problem.

    Solution one: TLE

    It literally translates what is described in the problem. There are n rounds, and we turn on and off the corresponding lights.

    The time complexity of outer layer is O(n).

    The time complexity of inner layer is 1/2 + 1/3 + 1/4 + ... , it is O(n). 

    The total time complexity is O(n * n). For this question, there is no doubt to be declined. TLE!!!

    class Solution {
    public:
        int bulbSwitch(int n) {
            vector<int> lights(n, 1);
            int cnt = n;
            for(int i = 1; i < n; i++){
                int gap = i;
                for(int j = gap ; j < n; j += gap + 1){
                    if(lights[j] == 1){
                        lights[j] = 0;
                        cnt--;
                    } else {
                        lights[j] = 1;
                        cnt++;
                    }
                }
                gap++;
            }
            return cnt;
        }
    };

    Solution two: TLE

    Since I am declined by the system, so optimize it. How?

    Think deeply, I found that the lights are on only if it is switched odd times. For a number, it has to have odd common divisor. I know how to find the number of common divisor for a given number in O(n ^1/2). Adding the traverse complexity, the total time complexity is O(n ^ 3/2). It is also declined.

    class Solution {
    public:
        int bulbSwitch(int n) {
            int lights_cnt = 0;
            for(int i = 1; i <= n; i++){
                if(common_divisor_count(i) % 2){
                    lights_cnt++;
                }
            }
            return lights_cnt;
        }
    private:
        int common_divisor_count(int n){
            int cnt = 0;
            for(int i = 1; i * i <= n; i++){
                if(n % i == 0){
                    cnt++;
                    if(n / i != i){
                        cnt++;
                    }
                }
            }
            return cnt;
        }    
    };

    Solution three: math (AC)

    From leetcode discussion, smart brains delivered the most brilliant solutions.

    For a given number, only those who is a square of a number have odd common divisor. It is obvious from my code of solution two. 

    That means the number of lights on, equals to how many square numbers from 1 to n.

    Just return sqrt(n).

    Summary:

    Since Leetcode only accepts the most brilliant solutions, but I like to think of a computer philosophy. For this problem, it is pure math. I am not that smart guys, can not return the answer by a function call. We should applaud for the smart solutions. But I think it is still valuable to find an approach to optimize the solution step by step.

  • 相关阅读:
    (转)typedef用法
    (转)在用户空间发生中断时,上下文切换的过程
    (转)内核中断,异常,抢占总结篇
    (转)中断上下文和进程上下文的区别
    (转)C中的volatile用法
    (转)gcc学习笔记
    (转)C系程序员面试必知必会之大端小端
    (转)我在北京工作这几年 – 一个软件工程师的反省
    (转)忠告
    Linux下VLAN功能的实现 (转)
  • 原文地址:https://www.cnblogs.com/wdw828/p/6865835.html
Copyright © 2020-2023  润新知