劍指offer.C++.code11-15

11. 二進制中1的個數(shù)

  • 輸入一個整數(shù),輸出該數(shù)二進制表示中1的個數(shù)。其中負數(shù)用補碼表示。
// Solution:位運算
// Tips:整數(shù)右移一位與整數(shù)除以二在數(shù)學(xué)上等價,但除法效率很低
// (1)如果整數(shù)右移一位,再與1做與運算判斷最后一位是不是1,負數(shù)會造成死循環(huán)
// (2)因此,采用整數(shù)與1按位與,然后把1左移1位,再按位與...
// (3)把一個整數(shù)減去1,再和原整數(shù)按位與,會將最右邊的1變成0;所以一個整數(shù)的二進制有多少1,就可進行多少次操作。
class Solution {
public:
     int  NumberOf1(int n) {
         /*(2)
         int count = 0;
         unsigned int flag = 1;
         while (flag) {
             if (n & flag) {
                 count ++;
             }
             flag = flag << 1;
         }
         return count;*/
         // (3)
         int count = 0;
         while(n) {
             count ++;
             n = n & (n-1);
         }
         return count;
     }
};

12. 數(shù)值的整數(shù)次方

  • 給定一個double類型的浮點數(shù)base和int類型的整數(shù)exponent。求base的exponent次方。
// Solution: 需要考慮多種邊界條件,以及使用斐波那契乘方、位運算提高循環(huán)乘法效率
// Tips:(1)考慮指數(shù)<=0,小于0時需要先求|e|,再求倒數(shù),此時要求base!=0;
//      (2)e=0時,0^0沒有意義,可考慮輸出1或0;
//      (3)double/float浮點數(shù)判斷相等,不使用==,|做差|<sigma;

class Solution {
public:
    bool gInvalidInput = false;
    
    double Power(double base, int exponent) {
        gInvalidInput = false;
        
        // 判斷指數(shù)e<0時,底數(shù)base是否等于0.0
        if (exponent <= 0 && (equal(base, 0.0))) {
            gInvalidInput = true;
            return 0.0;
        }
        
        // 判斷指數(shù)e<0時,需要求-e,并計算指數(shù)結(jié)果后求倒數(shù)
        unsigned int absExponent = (unsigned int)exponent;
        if (exponent < 0) {
            absExponent = (unsigned int)(-exponent);
        }
        
        double result = PowerWithUnsignedExponent(base, absExponent);
        if (exponent < 0)
            result = 1.0 / result;
        return result;
    }
    
    bool equal(double num1, double num2) {
        if ((num1 - num2 < 0.0000001) && (num1 - num2 > -0.0000001))
            return true;
        else
            return false;
    }
    
    double PowerWithUnsignedExponent(double base, unsigned int exponent) {
        /* 效率較低的循環(huán)乘法
        double res = 1.0;
        for (int i=1; i <= exponent; i ++) {
            res *= base;
        }*/
        
        // 使用a^n公式及位運算:
        // (1)n為偶數(shù),a^n = a^(n/2) * a^(n/2)
        // (2)n為奇數(shù),a^n = a^((n-1)/2) * a^((n-1)/2) * a
        if (exponent == 0)
            return 1;
        if (exponent == 1)
            return base;
        
        double res = PowerWithUnsignedExponent(base, exponent >> 1);
        res *= res;
        if (exponent & 0x1 == 1)
            res *= base;
        return res;
    }        
};

《劍指offer面試題12:打印1到最大的n位數(shù)》
(1)大數(shù)用字符串表示,最前補0;
(2)遞歸打印0~9的全排列。
(3)特殊輸入如0,-1等需要考慮。

《劍指offer面試題13:在O(1)時間刪除鏈表結(jié)點》給定單向鏈表頭指針和一個結(jié)點指針,刪除該結(jié)點
(1)O(n)順序找到要刪除結(jié)點的前一個結(jié)點, 更改pNext;
(2)O(1)復(fù)制下一個結(jié)點,刪除下一個結(jié)點,尾結(jié)點費時(另需考慮僅一個結(jié)點),時間復(fù)雜度=[(n-1)*O(1)+O(n)]/n=O(1)。

13. 調(diào)整數(shù)組順序使奇數(shù)位于偶數(shù)前面(注意erase時,iterator需要變化)

  • 輸入一個整數(shù)數(shù)組,實現(xiàn)一個函數(shù)來調(diào)整該數(shù)組中數(shù)字的順序,使得所有的奇數(shù)位于數(shù)組的前半部分,所有的偶數(shù)位于位于數(shù)組的后半部分,并保證奇數(shù)和奇數(shù),偶數(shù)和偶數(shù)之間的相對位置不變。
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        if (array.size() == 0) {
            return;
        }
        vector<int> right;
        vector<int>::iterator itArray;
        for (itArray = array.begin(); itArray != array.end(); itArray ++) {
            if (isEven(*itArray)) {
                right.push_back(*itArray);
                array.erase(itArray);
                itArray --; // 因為刪除vector元素后,循環(huán)itArray++會導(dǎo)致跳過訪問一個元素,以及后續(xù)訪問溢出
            }
        }
        vector<int>::iterator itRight;
        for (itRight = right.begin(); itRight != right.end(); itRight++) {
            array.push_back(*itRight);
        }
    }
    // 解耦判斷條件
    bool isEven(int n) {
        return !(n & 1);
    }
};

14. 鏈表中的倒數(shù)第k個結(jié)點

  • 輸入一個鏈表,輸出該鏈表中倒數(shù)第k個結(jié)點。
// Tips:(1)pListHead==NULL; (2)unsigned int k==0時, k-1是4294967295; (3)鏈表個數(shù)<k.
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if (pListHead == NULL || k == 0) {//k==0時,不返回,unsigned int會導(dǎo)致循環(huán)崩潰
            return NULL;
        }
        
        ListNode* pAhead = pListHead;
        ListNode* pBehind = pListHead;
        for (unsigned int i=0; i < k-1; i ++) {
            if (pAhead->next != NULL) {//鏈表個數(shù)小于k時
                pAhead = pAhead->next;
            } else {
                return NULL;
            }
        }
        
        while (pAhead->next != NULL) {
            pAhead = pAhead->next;
            pBehind = pBehind->next;
        }
        return pBehind;
    }
};

15. 反轉(zhuǎn)鏈表

  • 輸入一個鏈表,反轉(zhuǎn)鏈表后,輸出鏈表的所有元素。
// Solution:使用三個指針pPrev,pNode,pNext完成反轉(zhuǎn)
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode* pPrev = NULL;
        ListNode* pNode = pHead;
        // ListNode* pReverseHead = NULL;  
        while (pNode != NULL) {
            ListNode* pNext = pNode->next;
            // if (pNext == NULL) {
            //     pReverseHead = pNode;
            // } 
            pNode->next = pPrev;
            pPrev = pNode;
            pNode = pNext;
        }
        // return pReverseHead;
        return pPrev;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.把二元查找樹轉(zhuǎn)變成排序的雙向鏈表 題目: 輸入一棵二元查找樹,將該二元查找樹轉(zhuǎn)換成一個排序的雙向鏈表。 要求不...
    曲終人散Li閱讀 3,518評論 0 19
  • 刷題啦刷題啦,劍指offer好像比較有名,所以就在??途W(wǎng)上刷這個吧~btw,刷了一些題發(fā)現(xiàn)編程之美的題好典型?。。?..
    Cracks_Yi閱讀 495評論 0 1
  • 說明: 本文中出現(xiàn)的所有算法題皆來自??途W(wǎng)-劍指Offer在線編程題,在此只是作為轉(zhuǎn)載和記錄,用于本人學(xué)習(xí)使用,不...
    秋意思寒閱讀 1,222評論 1 1
  • 劍指 offer 在一個二維數(shù)組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成...
    faremax閱讀 2,329評論 0 7
  • 他生前我不識君,看個《縱情四?!愤€把他當(dāng)成陳志朋。那時候娛樂匱乏,接觸港臺的東西也少。后來他死了,我忽然就喜歡上他...
    文藝招財喵閱讀 518評論 2 1

友情鏈接更多精彩內(nèi)容