牛客网剑指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];
    }
};

原文地址:https://www.cnblogs.com/donzoru/p/8718086.html

时间: 2024-10-10 22:31:45

牛客网剑指Offer习题集题解0的相关文章

二维数组中的查找-牛客网-剑指offer

1.问题描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 2.问题分析 水平方向.垂直方向二重循环查找 3.源代码 package www.nowcoder.com.conquerOffer.array; /** * 二维数组中的查找 * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整

重建二叉树-牛客网-剑指offer

1.问题描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 2.问题分析 2.1首先了解二叉树的结构 2.2了解二叉树的三种遍历顺序(前序遍历,中序遍历和后序遍历) 前序遍历:中左右 中序遍历:左中右 后序遍历:左右中 根据前序遍历序列和中序遍历序列,或后序遍历序列和中序遍历序列,能唯一确定二叉树. 2.3

《剑指offer》题解

有段时间准备找工作,囫囵吞枣地做了<剑指offer>提供的编程习题,下面是题解收集. 当初没写目录真是个坏习惯(-_-)||,自己写的东西都要到处找. 剑指Offer - 九度1524 - 复杂链表的复制 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先 剑指Offer - 九度1508 - 把字符串转换成整数 剑指Offer - 九度1504 - 把数组排成最小的数 剑指Offer - 九度1503 - 二叉搜索树与双向链表 剑指Offer - 九度1390 - 矩形覆盖 剑

剑指offer习题集1

1.打印二叉树 程序很简单,但是其中犯了一个小错误,死活找不到,写代码要注意啊 这里左右子树,要注意是node->left,结果写成root->left vector<int> PrintFromTopToBottom(TreeNode *root) { vector<int> res; if (NULL == root) return res; TreeNode* node; deque<TreeNode*> tmp; tmp.push_back(root

剑指offer习题集

1.重载赋值运算符函数:(具体见代码) //普通做法 CMyString& CMyString::operator=(const CMyString& str) { if (this == &str) return *this; delete[] m_Pdata; m_Pdata = new char[strlen(str.m_Pdata)+1]; strcpy(m_Pdata,str.m_Pdata); return *this; } //更加安全的做法,普通做法在new内存不足

牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端

   总结:    重建二叉树:其实就是根据前序和中序重建得到二叉树,得到后续,只要输出那边设置输出顺序即可 [编程题]重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 完整通过代码: 先新建一个二叉树的类 public class TreeNode { int val; TreeNode left

剑指offer习题集2

1.把数组排成最小的数 class Solution { public: static bool compare(const string& s1, const string& s2) { string t1 = s1 + s2; string t2 = s2 + s1; return t1 <= t2? true : false; } string PrintMinNumber(vector<int> numbers) { string str; int i, len

【剑指offer】统计0到n之间1的个数[数学]

问题描述 给定一个十进制整数N,求出从1到N的所有整数中出现"1"的个数. 例如:N=2时 1,2出现了1个 "1" . N=12时 1,2,3,4,5,6,7,8,9,10,11,12.出现了5个"1". //暴力求解 long CountOnes(long n) { int i,j;//循环变量 int ncount=0;//计数 for (i=1; i<=n; i++) { j=i; while(j!=0) { if (j%10==1

剑指offer python版 0到n-1中缺失的数字

def aa(nums,n): for i in range(n): if i ==nums[i]: i +=1 else: return i print(aa([0,1,2,3,4,5,7],8)) 原文地址:https://www.cnblogs.com/xzm123/p/9869226.html