ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二刷剑指——壹

2021-05-05 20:02:00  阅读:209  来源: 互联网

标签:遍历 int 复杂度 ret 二刷 vector 数组


文章目录

1.数组中重复的数字

找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

方法1:

sort排序后,遍历数组,前面的值和后面的值相等即可

时间复杂度:nongn;

空间复杂度:快排需要递归,栈桢消耗 longn

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int count=0;
        for(int i=0;i<nums.size()-1;i++)
        {
            if(nums[i]==nums[i+1])
            {
                count=nums[i];
                break;
            }
        }
        return count;


    }
};

方法2:

统计排序、找出统计数组之中,值大于1的选项,然后+1返回

时间复杂度:O(n);

空间复杂度: O(n);

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        vector<int> ret(nums.size(),0);
        for(auto &e:nums)
        {
            if(ret[e]!=0)
            return e;
            ret[e]++;
        }
        return 0;

    }
};

2.二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

在这里插入图片描述

时间复杂度:O(m*n)

空间复杂度:O(1)

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { 
        if(matrix.size()==0)
        return false;
        
        int row=0;
        int col=matrix[0].size()-1;

        while(row>=0&&row<matrix.size()&&col>=0&&col<matrix[0].size())
        {
            if(matrix[row][col]>target)
                col--;
            else if(matrix[row][col]<target)
                row++;
            else
                return true;
        }
        return false;

    }
};

3. 替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

遍历s,遇到空格,则str+=“%20”,其余情况之下,+=s[i]

【注意:先开辟好str的空间,避免发生增容,导致发生拷贝】

时间复杂度:O(n)

空间复杂度:O(n)

class Solution {
public:
    string replaceSpace(string s) {
        string str;
        str.reserve(s.size());
        for(int i=0;i<s.size();i++)
        {
            if(s[i]==' ')
            str+="%20";
            else
            str+=s[i];
        }
        return str;

    }
};

4.从尾到头打印链表

方法1:递归

链表天然具有递归属性

时间复杂度:O(N) 遍历整个链表

空间复杂度: O(N) 栈桢消耗n,返回数组n

class Solution {
public:
    void _reversePrint(ListNode* head,vector<int> &ret)
    {
        if(head==NULL)
        return ;

        _reversePrint(head->next,ret);
        ret.push_back(head->val);
    }
    vector<int> reversePrint(ListNode* head) {
        vector<int> ret;
        _reversePrint(head,ret);
        return ret;
    }
};

方法2:遍历reverse

遍历链表,将所有的内容添加至数组之中

然后将数组逆转

时间复杂度: O(N) 遍历整个链表

空间复杂度:O(N) 返回数组消耗

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> ret;
       ListNode* cur=head;
        while(cur)
        {
            ret.push_back(cur->val);
            cur=cur->next;
        }
        reverse(ret.begin(),ret.end());
        return ret;
 
    }
};

5.重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

在前序中找根节点,然后去中序之中寻找该根节点的位置,然后在中序之中判断该节点是否还有左右子树

时间复杂度:O(N^2):需要每次需要在中序之中遍历寻找根节点的位置

空间复杂度:O(N) 开辟N个节点空间、递归深度O(N)

class Solution {
public:
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int &prev,int &inor_begin,int &inor_end)
    {
        if(prev>=preorder.size()||inor_begin>inor_end)
            return NULL;
        
        TreeNode *root=new TreeNode(preorder[prev]);//构造根节点

        int start=inor_begin;
        while(start<inor_end)
        {
            if(inorder[start]==preorder[prev])
                break;
            start++;
        }

        int end=start-1;
        if(inor_begin<=end)//还有左区间
            root->left= _buildTree(preorder,inorder,++prev,inor_begin,end);
        else
            root->left=NULL;

        int begin=start+1;
        if(begin<=inor_end)//还有右区间
            root->right=_buildTree(preorder,inorder,++prev,begin,inor_end);
        else    
            root->right=NULL;
        
        return root;
        
    } 

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        //在前序中找根节点、找到后去中序遍历中找左右子树

        int prev=0;
        int inor_begin=0;
        int inor_end=inorder.size()-1;

        return _buildTree(preorder,inorder,prev,inor_begin,inor_end);
    }
};

6.用两个栈实现队列

定义两个栈 -> st1、st2

入数据入到栈st1,当需要出数据的时候判断st2是否为空,不为空则直接从st2之中出

为空则将st1的全部内容倒过来,然后再出数据

class CQueue {
public:
    CQueue() {}//自定义类型、自动调用构造函数
    
    void appendTail(int value) {
        st1.push(value);
    }
    
    int deleteHead() {
        if(st2.empty())
        {
            while(!st1.empty())
            {
                st2.push(st1.top());
                st1.pop();
            }
        }
        if(st2.empty())
        return -1;
        
        int val=st2.top();
        st2.pop();
        return val;
    }

    stack<int> st1;
    stack<int> st2;
};

7.斐波那契数列

方法1:递归法(超时)

方法2:三指针迭代法(first=1、second=0、third=0)

时间复杂度 :O(N)

空间复杂度:O(1)

class Solution {
public:
    int fib(int n) {

        int first=1;
        int second=0;
        int third=0;

        for(int i=0;i<n;i++)
        {
            third=(first+second)%1000000007;
            first=second;
            second=third;
        }
        return third;

    }
};

8.青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

将题目转换一下就是: 1 1 2 3 5 斐波那契数列的斐波那契数列

class Solution {
public:
    int numWays(int n) {
        // 1 1 2 3 5 斐波那契数列

        int first=0;
        int second=1;
        int third=1;

        for(int i=0;i<n;i++)
        {
            third=(second+first)%1000000007;
            first=second;
            second=third;
        }
        return third;
    }
};

9.旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKb5HBSs-1620214495795)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210505165624842.png)]

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int left=0;
        int right=numbers.size()-1;

        while(left<right)
        {
            int mid=left+(right-left)/2;
            
            if(numbers[mid]>numbers[right])
                left=mid+1;
            else if(numbers[mid]<numbers[right])
                right=mid;
            else//相等时
                right--;
        }
        return numbers[left];
    }
};

10.矩阵中的路径

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

深度搜索、回溯法:遍历搜索二维数组,找到第一个头节点之后,传入递归搜索函数,往四个方向进行搜索

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lMOebYOX-1620214495802)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210505154849105.png)]

标签:遍历,int,复杂度,ret,二刷,vector,数组
来源: https://blog.csdn.net/ych9527/article/details/116429097

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有