leetcode刷题记录&题解&c++代码 03-06

不知不觉就大三啦,前段时间开始系统地刷力扣为面试笔试做准备,看到有的易错地方和通过率比较低的题,觉得或许有同样在刷题的伙伴需要题解和代码,就决定捡起荒置的博客,对我刷过的题进行存档和整理,对我复盘应该也有一些帮助。
这里是c++选手,代码可能会有一些竞赛风格,而且对速度和使用内存没有太大的强迫症。这篇文章会按照“剑指offer”的顺序排列
刚开始写class简直是痛苦…不过收获也挺多的

剑指 Offer 03. 数组中重复的数字
题意:找出数组中任意一个重复的数字(数组中数据大小都在0~长度-1)
数据范围:长度 ≤ \leq 1e5;
思路:
1.sort后直接比较相邻两元素是否相等,时间复杂度 O ( n log ⁡ 2 n ) O(n\log_{2}n) O(nlog2n) ,几乎不需新开什么东西;
2.用数组记录一个数字是否出现过,时间复杂度 O ( n ) O(n) O(n) ,需要额外开一个数组。
懒惰的我当然是方法2,时间是40ms超过83%,空间22.8M超过50%;

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int n=nums.size();
        int apr[100000+5]={0};
        for(int i=0;i<n;i++)
            if(apr[nums[i]])
                return nums[i];
            else apr[nums[i]]=1;
        return 0;
    }
};

剑指 Offer 04. 二维数组中的查找
题意:在一个每行每列都从上到下/从左到右递增的二维数组里寻找给定整数;
限制:0 ≤ \leq n ≤ \leq 10000 ≤ \leq m ≤ \leq 1000
思路:
1.使用lower_bound查找该数,时间复杂度 O ( n log ⁡ 2 m ) O(n\log_{2}m) O(nlog2m) 战绩是惨烈的 32ms(38%) 12.8M(25%)
我一开始想着横着找一个区间,再在这两列找即可,后来发现这样是不能确保在有的情况下找到的。
2.记录行和列,从右上角(或左下角)开始寻找,在当前数字比目标数字大或小时都有可以去的地方,且放弃的那一行/列必定没有要找的数字,时间复杂度是 O ( n + m ) O(n+m) O(n+m) 20ms 98% 12.7M 44%,如果改成从左下角找会(估计由于数据原因)慢不少
本懒人当然是用的1…不过2挺巧妙的,就也写了一次
注意:
1.lower_bound和upper_bound的区别(前者是第一个大于等于,后者是第一个大于)
2.数组size为0时若不处理可能re;
3.lower_bound可能返回最末尾未定义处,若不处理会re;
bb:这道题虽然很简单…但是谢谢它帮我复健了许久不用的lower_bound…尤其是用在STL上的;还有就是,听歌写代码真容易bug,各种少个=

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int n=matrix.size(),m;
        if(n)m=matrix[0].size();
        if(n&&m)
        {
            for(int i=0;i<m;i++)
            {
                int pos=lower_bound(matrix[i].begin(),matrix[i].end(),target)-matrix[i].begin();
                if(pos<n&&matrix[i][pos]==target)
                    return true;
            }
        }
        return false;
    }
};

优化版

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int n=matrix.size(),m,x,y;
        if(n)m=matrix[0].size();
        if(n&&m)
        {
            x=0;y=m-1;
            while(x<n&&y>=0)
            {
                if(matrix[x][y]==target)return true;
                else if(matrix[x][y]>target)y--;
                else x++;
            }
        }
        return false;
    }
};

剑指 Offer 05. 替换空格
题意:把string里的空格替换为“%20”;
限制:0 ≤ \leq s 的长度 ≤ \leq 10000
思路:直接扫描s一遍,另命一个string存储答案。若用string操作会比较慢
不过这道题好像大家都是0ms,我反而用了很大空间233
别的语言貌似写起来很快(虽然一共也没写几行233)

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

剑指 Offer 06. 从尾到头打印链表
题意:给定一个链表,用vector反过来存该链表每个节点的val;
思路:
1.遍历一次链表,正序存储下val,再头尾两两交换/新建一个vector反序存储一次
2.遍历一次链表获取链表长度,再遍历一次直接找出该存储的位置
两个思路都一样的丑,我就选了2 4ms(89%) 8.4M(89%)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        ListNode* pos=head;
        int len=0,cnt=0;
        while(pos!=NULL)
        {
            len++;
            pos=pos->next;
        }
        vector<int>ans(len,0);
        pos=head;
        while(pos!=NULL)
        {
            cnt++;
            ans[len-cnt]=pos->val;
            pos=pos->next;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值