1. 程式人生 > >[LeetCode] Number of 1 Bits & Reverse Integer

[LeetCode] Number of 1 Bits & Reverse Integer

目錄:
1.Number of 1 Bits  - 計算二進位制1的個數 [與運算]
2.Contains Duplicate - 是否存在重複數字 [遍歷]
3.Reverse Integer - 翻轉整數 [int邊界問題]
4.Excel Sheet Column Number - Excel字串轉整數 [簡單]
5.Power of Two & Happy Number - 計算各個位數字 [%10 /10]


一.Number of 1 Bits 

題目概述:
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the 
Hamming weight).
For example, the 32-bit integer ’11' has binary representation 

00000000000000000000000000001011
so the function should return 3.

解題方法:

三種方法包括:
        1.依次和0x1進行&與運算,若結果為1則加1,表示1個數,再右移;
        2.推薦的方法,n&(n-1),直到為0,次數為1的個數;
        3.n取2模,依次判斷個位是否為1,在n/2移位,常規方法。
其中uint32_t為32位無符號型別資料,參考地址
Power of Two題目也可以通過return (n > 0) && (!(n & (n - 1)))一句話實現。
Reverse Bits

題目也可以<<移位實現。

我的程式碼:

/*
 * uint32_t為32位無符號型別資料 思路:數字移位
 */
int hammingWeight(uint32_t n) {
    //第一種方法 考查移位及與運算&
    int result=0, left=0;
    while(0 != n)
    {
        left = n & 0x1;
        result += left;
        n = n >> 1;
    }
    return result;
    
    //第二種方法 
    int re = 0;
    while(0 != n)
    {
        n = n&(n - 1);
        ++re;
    }
    return re;
    
    //第三種方法  求2模
    int count = 0;  
    while (n) 
    {  
        if (n % 2 == 1) 
        {  
            ++count;  
        }  
        n /= 2;  
    }  
    return count;  
}


二.Contains Duplicate

題目概述:
Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.


題目解析:
題目是給定一個整數陣列,判斷該陣列中是否存在重複的數字。簡單AC的方法比較簡單,兩層迴圈判斷;但是如果要求是O(n)的時間和O(1)的空間,怎樣實現呢?騰訊的筆試題就考到了。又見重複判斷II III題。


我的程式碼:

bool containsDuplicate(int* nums, int numsSize) {
    //最傻的方法迴圈判斷
    int i,j;
    if(numsSize==0)
        return false;
    for(i=0;i<numsSize;i++)
    {
        for(j=i+1;j<numsSize;j++)
        {
            if(nums[i]==nums[j])
            {
                return true;  //表示存在重複的
            }
        }
    }
    return false;
}

推薦程式碼:

三.Reverse Integer

題目概述:
Reverse digits of an integer.
Example1:x = 123, return 321
Example2:x = -123, return -321


解題思路:
該題主要是考察整數的翻轉問題,最簡單的方法就是:通過"%10"計算個位數字和"/10"迴圈進行,直到整數為結果0;但是你需要注意的是:
        1.負數的轉換x=x*(-1)
        2.整數越界,int型範圍是(-2147483648~2147483647),4位元組。當x=1534236469時,應該輸出0而不是9646324351或溢位後的數
        3.需要注意一個特殊的用例:x=-2147483648。此時x=x*(-1)=2147483648溢位,結果應是0。
故此處需要把整數範圍的判斷指定出來講解,沒考慮整數溢位的程式碼如下:

//翻轉數字 顯然採用前面做過的%10提取個位和/10方法
int reverse(int x) {
    int i,j;
    int num;      //儲存位數
    int result;   //結果
    bool flag;    //是否是負數 true負數
    
    if( (x>=0&&x<10)||(x<0&&x>-10)) return x;
    if(x>0) 
        flag=true;
    else {
        flag=false;
        x=x*(-1);
    }
    result=0;
    while(x!=0) {
        result=result*10+x%10;   //結果
        x=x/10;
    }
    if(flag==true)
        return result;
    else
        return result*(-1);
}

正確程式碼:

重點是類似於Java的Integer.MAX_VALUE 這種直接可用的數值型的最大值定義,C語言採用#include <limits.h>裡面的INT_MIN和INT_MAX,而不是寫一長串數字。
/**
 * 翻轉數字 剛做完翻轉二叉樹做該題還是感覺數字親切點
 * 顯然採用前面做過的%10提取個位和/10方法
 * 方法很簡單 但是需要注意越界和x==-2147483648變成正數時溢位
 */ 
int reverse(int x) {
    int i,j;
    int num;      //儲存位數
    int result;   //結果
    bool flag;    //是否是負數 true負數
    
    if( (x>=0&&x<10)||(x<0&&x>-10)) return x;
    if(x==INT_MIN)   //否則扭轉溢位 INT_MIN=-2147483648
        return 0;
    if(x>0) { 
        flag=true;
    }
    else {
        flag=false;
        x=x*(-1);
    }
    result=0;
    while(x!=0) {
        if(x!=0&&result>INT_MAX/10) {  //214748364
            return 0;
        }
        result=result*10+x%10;   //結果
        x=x/10;
        //printf("%d\n",result);
    }
    if(flag==true)
        return result;
    else
        return result*(-1);
}


四.Excel Sheet Column Number

題目概述:
Related to question Excel Sheet Column Title
Given a column title as appear in an Excel sheet, return its corresponding column number.
For example:

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28 


題目解析:
該類題目比較簡單,主要考察字串遍歷和整數進位制問題(26進位制),自己一次AC。

int titleToNumber(char* s) {
    int result;  
    int length;
    int i,j;
    
    if(s==NULL) return 0;
    
    length=strlen(s);
    result=0;
    
    //從右向左遍歷 個位右
    for(i=0; i<length; i++) {
        result=result*26+(s[i]-'A')+1;
    }
    return result;
}

五.Power of Two & Happy Number

題目概述:
判斷數字是否是2的次數數
判斷數字是否是happy數,結果為1則返回true
Example: 19 is a happy number
1^2 + 9^2 = 82
        8^2 + 2^2 = 68
        6^2 + 8^2 = 100
        1^2 + 0^2 + 0^2 = 1

主要考察計算數字每個位數的方法,即n%10和n=n/10的方法。

我的程式碼:
Power of Two
強推位操作判斷16=10000即高位為1其他為0,或通過一句話即可: 

bool isPowerOfTwo(int n) {
    int number;
    
    if(n<=0) return false;
    if(n==1) return true;       //1=2^0
    if(n%2!=0) return false;
    while(n>0) {
        if(n==1) {  //最後一個數字是1
            return true;
        }
        if(n%2!=0) {
            return false;
        }
        else {
            n=n/2;
        }
    }
}
Happy Number
bool isHappy(int n) { //重點:可能出現無限迴圈或陣列越界情況 哪種情況不是happy數
    int result;       //結果直至0
    int number;
    
    if(n<=0) return false;
    while(result!=1) {
        //計算result
        result = 0;
        while(n>0) {
            number = n%10;
            n = n/10;
            result = result + number*number;
        }
        if(result==1) {
            return true;
        }
        else if(result<10) { //輸入2返回false
            return false;
        }
        else {
            n = result;     //下一計算n為上次的結果
        }
    }
}



PS:最後希望文章對您有所幫助,這都是自己A題的一些筆記和心得,同時真心建議你自己動手做做LeetCode。以前我也不信邪,現在信了~
(By:Eastmount 2015-9-14 凌晨5點半 http://blog.csdn.net/eastmount/)