1. 程式人生 > >leetcode-788-Rotated Digits(使用vector替代if else的逐個判斷)

leetcode-788-Rotated Digits(使用vector替代if else的逐個判斷)

there digi font mission exp 標準 很慢 other positive

題目描述:

X is a good number if after rotating each digit individually by 180 degrees, we get a valid number that is different from X. Each digit must be rotated - we cannot choose to leave it alone.

A number is valid if each digit remains a digit after rotation. 0, 1, and 8 rotate to themselves; 2 and 5 rotate to each other; 6 and 9 rotate to each other, and the rest of the numbers do not rotate to any other number and become invalid.

Now given a positive number N, how many numbers X from 1 to N are good?

Example:
Input: 10
Output: 4
Explanation: 
There are four good numbers in the range [1, 10] : 2, 5, 6, 9.
Note that 1 and 10 are not good numbers, since they remain unchanged after rotating.

Note:

  • N will be in range [1, 10000].

要完成的函數:

int rotatedDigits(int N)

說明:

1、這道題給定一個數字N,要求判斷在[1,N]之間的數有多少個“好數”。好數的判斷標準是這樣的:數位上的每個數字翻轉180度,翻轉之後的所有數位還能構成數字的,並且該數字與翻轉之前的不一樣,那麽就是一個好數。

數字0/1/8,180度翻轉之後還是本身,數字3/4/7,180度翻轉之後形成不了數字,數字2和數字5翻轉之後是對方,數字6和數字9翻轉之後也是對方。

比如數字17,反轉之後不是數字,那麽不是好數。比如數字18,翻轉之後還是數字18,也不是好數。比如數字19,翻轉之後是16,是好數。

2、明白題意之後,這道題筆者最開始想要看看有沒有什麽數學規律,能夠比較便捷地計算,但後來發現,好像還是暴力叠代最容易做了。

不過暴力叠代法中間也有技巧。

碰到一個數字,不斷地對10取余數,取出末位,判斷末位是三種數字中的哪一種。

這個判斷如果一個個去判斷,還是很慢。可以用set.count(),會快很多。但還有一種更快的做法,如下述代碼:

    int rotatedDigits(int N) 
    {
        vector<int>judge={1,1,2,0,0,2,2,0,1,2};//0表示形成不了有效數字
        int j,t,count=0;                       //2表示出現了2/5/6/9
        bool flag=0;
        for(int i=1;i<=N;i++)
        {
            j=i;
            flag=0;
            while(j)
            {
                t=j%10;
                if(judge[t]==0)
                {
                    flag=0;//這裏要flag=0,不然比如32,就出錯了
                    break;
                }
                else if(judge[t]==2)
                    flag=1;
                j/=10;
            }
            if(flag==1)
                count++;
        }
        return count;
        
    }

上述代碼實測9ms,beats 37.13% of cpp submissions。

3、改進:

看了一些discuss的代碼,發現大家大體上都是暴力叠代法實現的,但是他們就是能跑到4ms……

看了他們的方法,自己實現了一下,代碼分享給大家,如下:

    bool isvalid(int n)
    {
        bool flag=false;
        while(n>0)
        {
            if(n%10==2) 
                flag=true;
            else if(n%10==5) 
                flag = true;
            else if(n%10==6) 
                flag=true;
            else if(n%10==9) 
                flag=true;
            else if(n%10==3) 
                return false;
            else if(n%10==4) 
                return false;
            else if(n%10==7) 
                return false;
            n/=10;
        }
        return flag;
    }
    int rotatedDigits(int N) 
    {
        int res=0;
        for(int i=1;i<=N;i++)
        {
            if(isvalid(i))
                res++;
        }
        return res;
    }

代碼思想大同小異,筆者2中的代碼,也是逐個判斷是否為好數,然後count++。但是判斷的過程不一樣。

筆者在函數內部實現判斷,上述代碼是另外定義一個函數來判斷,照理來說,調用函數這個過程會花費一些時間。

此外,筆者的代碼多了一個要判斷flag的值是否為1的過程,而上述代碼沒有這個過程。

總的來說,比起大神的代碼,多了判斷flag==1的的過程,少了函數調用的過程,這樣能省5ms……

上述代碼實測4ms,beats 95.00% of cpp submissions。

leetcode-788-Rotated Digits(使用vector替代if else的逐個判斷)