牛客网剑指Offer习题集题解0

Posted donzoru

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客网剑指Offer习题集题解0相关的知识,希望对你有一定的参考价值。

https://www.nowcoder.com/ta/coding-interviews

牛客个人界面欢迎互fo

0x00 二维数组中的查找

没啥难得,直接上二分就好了。注意二分别写挫了。
时间复杂度为\(O(nlogn)\)

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int siz = (int)array.size();
        for(int i=0;i<siz;++i){
            int l=0,r=(int)array[i].size();
            while( l < r){
                int m = l+r>>1;
                if(array[i][m]==target) return true;
                if(array[i][m] > target) r = m;
                else l = m + 1;
            }
        }
        return false;
    }
};

0x01 替换空格

最开始以为直接输出就好了呢,结果是更改字符串中的内容(尴尬)。
倒序更改就可以了,注意特殊情况。
时间复杂度为\(O(n)\)

class Solution {
public:
    void replaceSpace(char *str,int length) {
        if( str == NULL || length <= 0 ) return;
        int cnt = 0 , len = 0;
        for(int i=0;str[i];++i){
            len++;
            cnt += (str[i]==‘ ‘);
        }
        int newlength = len + 2*cnt;
        if(newlength > length) return;
        for(int j=newlength,i=len;i>=0;--i){
            if(str[i]!=‘ ‘) str[j--]=str[i];
            else {
                str[j--]=‘0‘;
                str[j--]=‘2‘;
                str[j--]=‘%‘;
            }
        }
    }
};

0x02 从尾到头打印链表

返回值为vector,很容易想到遍历一遍链表把值推进vector里。
时间复杂度\(O(n)\)

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> res;
        res.clear();
        if( head == NULL ) return res;
        while(head != NULL){
            res.push_back(head->val);
            head = head->next;
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

0x03 重建二叉树

根节点插入到树中,再分成左右子树递归即可,poj原题。
时间复杂度\(O(n)\),因为每个节点都递归遍历过一次。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if( pre.size() <= 0 ) return NULL;
        int root = pre[0],en = -1;
        TreeNode * Node = new TreeNode(root);
        if( pre.size() == 1 ) return Node;
        vector<int> pp,vv;
        for(int i=0;i<(int)vin.size();++i) {
            if( vin[i]==root ) {
                en = i;
                break;
            }
            pp.push_back(pre[i+1]);
            vv.push_back(vin[i]);
        }
        Node -> left = reConstructBinaryTree(pp,vv);
        pp.clear(),vv.clear();
        for(int i=en+1;i<(int)vin.size();++i){
            pp.push_back(pre[i]);
            vv.push_back(vin[i]);
        }
        Node -> right = reConstructBinaryTree(pp,vv);
        return Node;
    }
};

0x04 用两个栈实现队列

stack1实现Push操作,要Pop的时候就清空stack1,塞满stack2,这时候stack2正常Pop就好了。
时间复杂度为均摊\(O(1)\)。虽然看上去复杂度很高,但实际上\(O(n)\)的“倒腾”操作的次数不会很多。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
        return ;
    }

    int pop() {
        if((int)stack2.size()==0){
            while(stack1.size()){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        int res = stack2.top();
        stack2.pop();
        return res;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

0x05 旋转数组的最小数字

题目说的很绕,其实就是求数组的最小值,\(O(n)\)跑一遍求解就好了。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int siz = (int)rotateArray.size();
        if(siz == 0) return 0;
        int mini = INT_MAX;
        for(int i=0;i<siz;++i)
            mini = mini < rotateArray[i] ? mini : rotateArray[i];
        return mini;
    }
};

0x06 斐波那契数列

经典题目,我就随便写个递归就过去了,常数有点高。
时间复杂度为\(O(n)\)
能打表就好了啊

class Solution {
public:
    int Fibonacci(int n) {
        if(n==0) return 0;
        else if(n==1 || n==2) return 1;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }
};

0x07 跳台阶

经典题目,杭电oj里面有。其实就是斐波那契数列的变种。
很明显在第n个台阶只能从n-1阶和n-2阶走过来,所以 \(dp[n] = dp[n-1] + dp[n-2]\)
时间复杂度为\(O(n)\),手懒可以写递归比如我

class Solution {
public:
    int jumpFloor(int number) {
        if(number == 1 || number == 0) return 1;
        return jumpFloor(number-1) + jumpFloor(number-2);
    }
}; 

0x08 变态跳台阶

这回的递推公式就是从0到n-1了。
\(\begin{equation*} dp[n] = \sum_{i=1}^n dp[n-i] \end{equation*}\)
其实这题就是母函数,有兴趣可以看一眼。
时间复杂度为\(O(n^2)\)

class Solution {
public:
    int jumpFloorII(int number) {
       if(number <= 1) return 1;
       int a[20]={0}; 
       a[0]=a[1]=1;
       for(int i=2;i<=number;++i)
           for(int j=1;j<=i;++j)
               a[i]+=a[i-j];
       return a[number];
    }
};

0x09 矩形覆盖

同样是斐波那契的变种,在纸上画画就出来了。POJ原题,杭电oj上也有。
时间复杂度为\(O(n)\)

class Solution {
public:
    int rectCover(int number) {
        int a[40];
        a[1]=1,a[2]=2;
        for(int i=3;i<=number;++i)
            a[i]=a[i-1]+a[i-2];
        return a[number];
    }
};

以上是关于牛客网剑指Offer习题集题解0的主要内容,如果未能解决你的问题,请参考以下文章

牛客网剑指offer专题python解答JZ1---JZ12持续刷题中

牛客网剑指offer专题python解答JZ1---JZ12持续刷题中

牛客网剑指offer专题python解答JZ1---JZ12持续刷题中

牛客网习题剑指offer之数值的整数次方

手机牛客在线编程入口在哪

剑指offer得意之作——顺时针打印矩阵