剑指OFFER11-20

11.二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

class Solution {
public:
     int  NumberOf1(int n) {
        int cot=0;
        if(n<0)
        {
            n+=2147483648;
            cot++;
        }
        while(n!=0)
        {
            if(n%2)
            {
                cot++;
            }
            n/=2;
        }
        return cot;
     }
};

此题的二进制是32位的。

12.数值的整数次方

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

class Solution {
public:
    double Power(double base, int exponent) {
        double res=base;
        if(exponent==0){
            return 1.0;
        }else{
            if(exponent>0){
                for(int i=1;i<exponent;i++){
                    res*=base;
                }
                return res;
            }else{
                exponent=-exponent;
                for(int i=1;i<exponent;i++){
                    res*=base;
                }
                res=1.0/res;
                return res;
            }
        }
    }
};

注意指数有正负。

13.调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int oddnum=0,evennum=0;
        vector<int> odd,even;
        vector<int>:: iterator i,j,k;
        for(i=array.begin();i!=array.end();i++){
            if(*i%2){
                odd.push_back(*i);
            }else{
                even.push_back(*i);
            }
        }
        i=array.begin();
        for(j=odd.begin();j!=odd.end();j++){
            *i=*j;
            i++;
        }
        for(k=even.begin();k!=even.end();k++){
            *i=*k;
            i++;
        }
    }
};

时间复杂度o(n),如果不另外占用空间则需要o(n*2)。

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

输入一个链表,输出该链表中倒数第k个结点

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode *num[1005];
        ListNode *pList=pListHead;
        int cot=0;
        while(pList!=NULL){
            num[cot]=pList;
            pList=pList->next;
            cot++;
        }
        if(cot<k)
            return NULL;
        return num[cot-k];
    }
};

注意K可能比节点个数小。

15.反转链表

输入一个链表,反转链表后,输出链表的所有元素。

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *last=pHead,*tmp=NULL;
        while(pHead!=NULL){
            last=pHead->next;
            pHead->next=tmp;
            tmp=pHead;
            pHead=last;
        }
        return tmp;
    }
};

16.合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode *head=new ListNode(1);
        ListNode *last=head;
        while(pHead1!=NULL&&pHead2!=NULL){
            int x=min(pHead1->val,pHead2->val);
            ListNode *tmp=new ListNode(x);
            last->next=tmp;
            last=tmp;
            if(pHead1->val<pHead2->val){
                pHead1=pHead1->next;
            }else{
                pHead2=pHead2->next;
            }
        }
        if(pHead1!=NULL&&pHead2==NULL){
            while(pHead1!=NULL){
                int x=pHead1->val;
                ListNode *tmp=new ListNode(x);
                last->next=tmp;
                last=tmp;
                pHead1=pHead1->next;
            }
        }
        if(pHead1==NULL&&pHead2!=NULL){
            while(pHead2!=NULL){
                int x=pHead2->val;
                ListNode *tmp=new ListNode(x);
                last->next=tmp;
                last=tmp;
                pHead2=pHead2->next;
            }
        }
        head=head->next;
        return head;
    }
};

写法上可以再简化一点。

17.树的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

bool check(TreeNode* p1, TreeNode* p2){
    if(p2==NULL)
        return 1;
    if(p1!=NULL&&p2!=NULL){
        if(p1->val==p2->val){
            if(check(p1->left,p2->left)&&check(p1->right,p2->right))
                return 1;
        }
    }
    return 0;
}
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if(pRoot1!=NULL&&pRoot2!=NULL){
            if(check(pRoot1,pRoot2)){
                return 1;
            }else{
                if(HasSubtree(pRoot1->left,pRoot2)){
                    return 1;
                }
                if(HasSubtree(pRoot1->right,pRoot2)){
                    return 1;
                }
            }
        }
        return 0;
    }
};

树B为空则算是不同,而且子结构不一定是子树,B可以是A中的任意一部分

18.二叉树的镜像

操作给定的二叉树,将其变换为源二叉树的镜像。

class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(!pRoot)
            return;
        swap(pRoot->left,pRoot->right);
        Mirror(pRoot->left);
        Mirror(pRoot->right);
    }
};

19.顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int len=matrix.size()-1,wid=matrix[0].size()-1;
        int x=0,y=0;
        vector<int> res;
        while(x<=wid&&y<=len){
            for(int i=x;i<=wid;i++)
                res.push_back(matrix[y][i]);
            for(int i=y+1;i<=len;i++)
                res.push_back(matrix[i][wid]);
            for(int i=wid-1;i>=x&&len!=y;i--)
                res.push_back(matrix[len][i]);
            for(int i=len-1;i>y&&x!=wid;i--)
                res.push_back(matrix[i][x]);
            x++;
            y++;
            wid--;
            len--;
        }
        return res;
    }
};

注意只有一行或一列的极限情况,还有四个角。

20.包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数

class Solution {
public:
    vector<int> stk;
    void push(int value) {
        stk.push_back(value);
    }
    void pop() {
        stk.erase(stk.end()-1);
    }
    int top() {
        return *(stk.end()-1);
    }
    int min() {
        int res=stk[0];
        for(int i=1;i<stk.size();i++)
            if(stk[i]<res)
                res=stk[i];
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值