美文网首页
剑指offer.C++.code11-15

剑指offer.C++.code11-15

作者: 小异_Summer | 来源:发表于2018-03-02 15:45 被阅读0次

11. 二进制中1的个数

  • 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
// Solution:位运算
// Tips:整数右移一位与整数除以二在数学上等价,但除法效率很低
// (1)如果整数右移一位,再与1做与运算判断最后一位是不是1,负数会造成死循环
// (2)因此,采用整数与1按位与,然后把1左移1位,再按位与...
// (3)把一个整数减去1,再和原整数按位与,会将最右边的1变成0;所以一个整数的二进制有多少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. 数值的整数次方

  • 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
// Solution: 需要考虑多种边界条件,以及使用斐波那契乘方、位运算提高循环乘法效率
// Tips:(1)考虑指数<=0,小于0时需要先求|e|,再求倒数,此时要求base!=0;
//      (2)e=0时,0^0没有意义,可考虑输出1或0;
//      (3)double/float浮点数判断相等,不使用==,|做差|<sigma;

class Solution {
public:
    bool gInvalidInput = false;
    
    double Power(double base, int exponent) {
        gInvalidInput = false;
        
        // 判断指数e<0时,底数base是否等于0.0
        if (exponent <= 0 && (equal(base, 0.0))) {
            gInvalidInput = true;
            return 0.0;
        }
        
        // 判断指数e<0时,需要求-e,并计算指数结果后求倒数
        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) {
        /* 效率较低的循环乘法
        double res = 1.0;
        for (int i=1; i <= exponent; i ++) {
            res *= base;
        }*/
        
        // 使用a^n公式及位运算:
        // (1)n为偶数,a^n = a^(n/2) * a^(n/2)
        // (2)n为奇数,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位数》
(1)大数用字符串表示,最前补0;
(2)递归打印0~9的全排列。
(3)特殊输入如0,-1等需要考虑。

《剑指offer面试题13:在O(1)时间删除链表结点》给定单向链表头指针和一个结点指针,删除该结点
(1)O(n)顺序找到要删除结点的前一个结点, 更改pNext;
(2)O(1)复制下一个结点,删除下一个结点,尾结点费时(另需考虑仅一个结点),时间复杂度=[(n-1)*O(1)+O(n)]/n=O(1)。

13. 调整数组顺序使奇数位于偶数前面(注意erase时,iterator需要变化)

  • 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
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元素后,循环itArray++会导致跳过访问一个元素,以及后续访问溢出
            }
        }
        vector<int>::iterator itRight;
        for (itRight = right.begin(); itRight != right.end(); itRight++) {
            array.push_back(*itRight);
        }
    }
    // 解耦判断条件
    bool isEven(int n) {
        return !(n & 1);
    }
};

14. 链表中的倒数第k个结点

  • 输入一个链表,输出该链表中倒数第k个结点。
// Tips:(1)pListHead==NULL; (2)unsigned int k==0时, k-1是4294967295; (3)链表个数<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会导致循环崩溃
            return NULL;
        }
        
        ListNode* pAhead = pListHead;
        ListNode* pBehind = pListHead;
        for (unsigned int i=0; i < k-1; i ++) {
            if (pAhead->next != NULL) {//链表个数小于k时
                pAhead = pAhead->next;
            } else {
                return NULL;
            }
        }
        
        while (pAhead->next != NULL) {
            pAhead = pAhead->next;
            pBehind = pBehind->next;
        }
        return pBehind;
    }
};

15. 反转链表

  • 输入一个链表,反转链表后,输出链表的所有元素。
// Solution:使用三个指针pPrev,pNode,pNext完成反转
/*
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;
    }
};

相关文章

  • 剑指offer.C++.code11-15

    11. 二进制中1的个数 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 12. 数值的整数次方...

  • 剑指

    遥望中原九点烟,风云直上七重天。 今朝再向江湖去,一剑流星谁比肩? 2011.10(1488)

  • 剑指

    1. 二维数组中查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照...

  • 全网最全剑指offer题目解答

    【剑指offer】Java版代码(完整版) 【剑指offer】1-10题 【剑指offer】11-20题 【剑指o...

  • 剑指offer

    第一题:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,...

  • 剑指BAT

    Android工作5年半了,一毕业就开始做这行。在现在这家公司工作了3年整,最近有换工作的打算,所以在猎聘...

  • 《剑指offer》

    4.调整数组顺序使奇数位于偶数前面 题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇...

  • 气剑指

    “聚气于指尖,凝其成剑,利可断金。”牢头对身边的狱卒说。 只见牢头举起的右手指尖逐渐变红,转而变白,隐隐发出音量很...

  • 剑指offer

    二维数组中查找数在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到...

  • 剑指苍穹

    逆天命,斩苍穹,吾乃修士,率性而为!《剑指苍穹》是一款逍遥仙侠MMORPG——群魔阻道,斩群魔;妖邪拦路,诛妖邪,...

网友评论

      本文标题:剑指offer.C++.code11-15

      本文链接:https://www.haomeiwen.com/subject/loonxftx.html