系列文章目录

图解算法数据结构刷题笔记01


本篇文章目录

  • 系列文章目录
  • 前言
  • 1、剑指 Offer 05. 替换空格
  • 2、剑指 Offer 06. 从尾到头打印链表
  • 3、剑指 Offer 09. 用两个栈实现队列
  • 4、剑指 Offer 20. 表示数值的字符串
  • 5、剑指 Offer 24. 反转链表
  • 6、剑指 Offer 30. 包含 min 函数的栈
  • 7、剑指 Offer 35. 复杂链表的复制
  • 8、剑指 Offer 58 - II. 左旋转字符串
  • 9、剑指 Offer 59 - I. 滑动窗口的最大值
  • 10、剑指 Offer 59 - II. 队列的最大值
  • 11、剑指 Offer 67. 把字符串转换成整数
  • 总结

前言

刷题来源:https://leetcode.cn/leetbook/detail/illustration-of-algorithm/
主要目的:

  • 复习数据结构与算法的核心知识点
  • 掌握互联网笔面试的主要算法题型,能过面试算法题。

内容概述:


1、剑指 Offer 05. 替换空格

战绩

思路

面试前先询问是否可以修改原字符串,可以就解法一:原地修改,不可以就解法二:遍历添加

代码
解法一:原地修改

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

解法二:遍历添加

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

2、剑指 Offer 06. 从尾到头打印链表

战绩

思路

先遍历一遍链表得到链表长度,根据链表长度构建结果数组,再遍历一遍链表,向结果数组从尾到头进行插入
注意结果数组边界不要溢出了!

代码

class Solution {public:vector<int> reversePrint(ListNode* head) {int count = 0;ListNode* cur = head;while(cur != NULL){count++;cur = cur->next;}cur = head;vector<int> ans(count);for(int i=count-1;i>=0;--i){ans[i] = cur->val;cur = cur->next;}return ans;}
};

3、剑指 Offer 09. 用两个栈实现队列

战绩

思路

队列的入队,辅助栈来数据就压入栈即可
队列的出队,
如果主栈和辅助栈都为空返回-1,
如果主栈为空,辅助栈非空,就把辅助栈中的元素全部依次压入主栈中并返回栈顶元素,
如果主栈非空,默认返回栈顶元素即可

代码

class CQueue {public:stack<int> a,b;//a辅助栈、b主栈CQueue() {}void appendTail(int value) {a.push(value);}int deleteHead() {if(b.empty() && a.empty())  return -1;else if( b.empty() && !a.empty() ) {while(!a.empty()){b.push(a.top());a.pop();}}int tmp = b.top();b.pop();return tmp;}
};

4、剑指 Offer 20. 表示数值的字符串

战绩

思路

这题之前特地发过一篇文章:剑指offer20题 表示数值的字符串 这题实在是太优雅了
记好三条规律和一个特别情况就能快速敲出

代码

class Solution {public:static void trim(string &s){if( !s.empty() ){s.erase(0,s.find_first_not_of(" "));s.erase(s.find_last_not_of(" ") + 1);}}bool isNumber(string s) {if (s.empty() || s.size() == 0) return false;trim(s);bool is_num = false;//判断数字是否出现过bool is_dot = false;//判断.是否出现过bool is_eorE = false;//判断e或者E是否出现过int i = 0,size = s.size();for (; i < size; i++) {//判定为数字,则标记is_numif (s[i] >= '0' && s[i] <= '9') {   is_num = true;//判定为.  需要前面没出现过.并且没出现过e} else if (s[i] == '.' && !is_dot && !is_eorE) {  is_dot = true;       //判定为e或者E,需要前面没出现过e,并且出现过数字} else if ((s[i]=='e' || s[i]=='E') && !is_eorE && is_num) {is_eorE = true;is_num = false;//为了避免123e这种请求,出现e之后就标志为false      //判定为+-符号,只能出现在第一位或者紧接e后面} else if (s[i] == '-' || s[i] == '+'){if(i!=0 && s[i-1] != 'e' && s[i-1] != 'E'){return false;}} else {return false;}}return is_num;}
};

5、剑指 Offer 24. 反转链表

战绩

思路

用cur指向要反转的节点。pre指向反转节点的上一个节点,初始为空。
只要cur不为空就继续遍历下一个节点,循环执行
先用tmp保存下一个节点免得找不到了,然后通过两指针操作反转节点

代码

class Solution {public:ListNode* reverseList(ListNode* head) {ListNode *cur=head,*pre=nullptr;while(cur!=nullptr){ListNode *tmp = cur->next;cur->next = pre;pre = cur;cur = tmp;}return pre;}
};

6、剑指 Offer 30. 包含 min 函数的栈

战绩

思路

这题跟用两个栈实现队列有点像,都是用两个栈来实现的,所以先直接定义主要栈和辅助栈
1、入栈时,先直接压入主要栈,如果比辅助栈顶元素小或者等于就压入辅助栈(注意辅助栈最为空的情况下不管大小都是要压入的,我在这里就踩了坑,检查好久才改正)
2、出栈时,先直接出主要栈的元素,如果和辅助栈相等就也出了
3、查看栈顶元素时,直接返回主要栈栈顶元素即可
4、查看当前栈最小元素时,直接返回辅助栈栈顶元素即可
总的来说,代码很简单,主要要理解辅助栈的作用,特别是入栈时的操作一定要注意!

代码

class MinStack {public:/** initialize your data structure here. */stack<int> sta,stb;//sta主要栈,stb辅助最小栈MinStack() {}void push(int x) {sta.push(x);if(stb.empty() || x <= stb.top()){stb.push(x);}}void pop() {if(sta.top() == stb.top()){stb.pop();}sta.pop();}int top() {return sta.top();}int min() {return stb.top();}
};

7、剑指 Offer 35. 复杂链表的复制

战绩

ps:这里之后就不放战绩图了,没啥用,专注解题思路和代码吧!

思路

这题第二次写只记得复制拆分了,具体的咋弄完全忘了,所以狼狈的看了一遍,又自己敲然后又敲错了,比对之后才更正,不多bb了。
三步走即可:
1、复制链表节点插入原节点和原节点后一个节点之间;
2、复制链表节点的随机节点
3、链表拆分
最关键的链表拆分踩坑就是,最后一个原节点本来是指向NULL的,但是复制之后就指向了和自己相同的复制节点,循环拆完后,要手动把最后一个节点指向空;

代码

class Solution {public:Node* copyRandomList(Node* head) {if(head == NULL) return NULL;//1、复制链表节点Node* cur = head;while(cur != NULL){Node* tmp = new Node(cur->val);tmp->next = cur->next; cur->next = tmp;cur = tmp->next;}//2、构建各新节点的randomcur = head;while(cur != NULL){if(cur->random != nullptr)cur->next->random = cur->random->next;cur = cur->next->next;}//3、拆分链表cur = head;               Node* newhead = head->next;Node* newcur = head->next;while(newcur->next != NULL){cur->next = newcur->next;cur = newcur->next;newcur->next = cur->next;newcur = cur->next;} cur->next = nullptr;return newhead;}
};

8、剑指 Offer 58 - II. 左旋转字符串

思路

这题太简单就遍历拼接就行了,但是也有比较秀的操作,利用C艹语法特性三次翻转解题

代码

class Solution {public:string reverseLeftWords(string s, int n) {reverse(s.begin(), s.begin() + n);reverse(s.begin() + n, s.end());reverse(s.begin(), s.end());return s;}
};

9、剑指 Offer 59 - I. 滑动窗口的最大值

思路
这题个人感觉是这组题目里面最难的一题,直接模拟的话就是定义左右边界分别为【i,j】,每往右一步就遍历一遍窗口里的最大值出来加入到结果数组中,这样时间复制度很高而且不符合题目要求.
所以,引入单调队列deque存储窗口内的元素,每轮窗口滑动移除了元素 nums[i - 1]nums[i−1] ,需将 dequedeque 内的对应元素一起删除。
每轮窗口滑动添加了元素 nums[j + 1] ,需将 deque 内所有 小于 nums[j + 1] 的元素删除。
这样一来,每次滑动后,单调队列的队首元素就是最大的值,用一个数组存起来即可。

代码

class Solution {public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> res;//存放结果if (nums.size()==0 || k==0) return res;deque<int> d;//单调队列for (int j=0, i=1-k; j<nums.size(); i++, j++) {//i左边界、j右边界if (i>0 && d.front()==nums[i-1]) d.pop_front();while (!d.empty() && d.back() < nums[j]) d.pop_back();d.push_back(nums[j]);//新元素入队列if (i>=0) res.push_back(d.front());}return res;}
};

10、剑指 Offer 59 - II. 队列的最大值

思路
队列queue么实现函数返回队列的最大值,所以,来个deque作为辅助队列存储队列的历史最大值
入队时,直接入队列a,如果辅助队列b非空并且b队列中比入队的值要小的值都出队,最后把改值加入辅助队列b
出队时,如果a为空返回-1,如果a非空且出队的值和b顶端的相同,那么b也出队,否则默认返回a队列的顶端的值即可。
max_value就是辅助队列b的front()

代码

class MaxQueue {public:deque<int> b;//单调队列queue<int> a;//队列,存储MaxQueue() {}int max_value() {return b.empty() ? -1 : b.front();}void push_back(int value) {a.push(value);while(!b.empty() && b.back() <= value)b.pop_back();b.push_back(value);}int pop_front() {if (a.empty()) return -1;if (a.front() == b.front()) b.pop_front();int tmp = a.front();a.pop();return tmp;}
};

11、剑指 Offer 67. 把字符串转换成整数

思路
这题也是困扰我好久,解题方法也很简单就是先处理空格和±符号,然后遍历转整数即可。
主要是INT类型的溢出问题,收获颇多,k神的处理方法真的是太秀了,就直接除2,这样就能进行运算而且不怕溢出了,我开始想用long来着,问题是测试用例就离谱还有连long范围都超了的,学到了k神的操作了,666;

代码

class Solution {public:int strToInt(string str) {int size = str.size();if (size == 0) return 0;int i=0;while (str[i] == ' ') //处理空格if (++i == size) return 0;int sign = 1;//处理符号if(str[i] == '-') sign = -1;if(str[i] == '-' || str[i] == '+') i++;int ans=0,bndry = INT_MAX / 10;//防止溢出while(str[i] >= '0' && str[i] <= '9'){if (ans > bndry || ans == bndry && (str[i]-'0') > 7) return sign == 1 ? INT_MAX : INT_MIN;ans = ans*10 + (str[i]-'0');//转整数i++;}return sign * ans;//不忘符号}
};

总结

这部分内容分几次安排才弄完,有数个题目有偷瞄或者搜索语法等的行为才敲出了过了,有2题对于第一遍的解法只有大概印象,思路混乱了,代码也敲不出来,最后只能去看了题解,我太菜了,所以,部分题目我还会再去尝试独立敲,直到能流畅的敲出来为止!

图解算法数据结构刷题笔记02相关推荐

  1. 算法入门刷题笔记 Day10 - A - 拓扑排序·一 -- D - K-th Path

    写在前面 好久没更新公众号和博客了,因为最近在研究新的方向,所以很少发文. 笔者接触编程只有一年,这一年间主要研究启发式算法在运筹学中的应用.但是由于编程基础薄弱,在进一步研究复杂运筹学问题时发现基础 ...

  2. 算法入门刷题笔记 Day2 K - Coat of Anticubism L - Five-In-a-Row M - Island Puzzl......

    写在前面 好久没更新公众号和博客了,因为最近在研究新的方向,所以很少发文. 笔者接触编程只有一年,这一年间主要研究启发式算法在运筹学中的应用.但是由于编程基础薄弱,在进一步研究复杂运筹学问题时发现基础 ...

  3. 基础夯实,字节内部总结240道算法LeetCode刷题笔记,直呼太全

    1.什么是算法 算法(algorithm,[ˈælɡərɪðəm],计算程序):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出.简单来说算法就是一系列的计算步骤,用来将 ...

  4. 【练习】2021下半年数据结构刷题笔记和总结 (三)栈 队列 链表 枚举算法

    题目来自书或者网站. 解密QQ 号--队列 回文字符串---栈 火柴棍等式 输入数字n,要求输出从1~n的全排列 [力扣]给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 ...

  5. 【练习】2021下半年数据结构刷题笔记和总结 (二) 树、查找-- 不同的排序算法、二叉排序树 平衡二叉树、哈希表查找、线索二叉树、

    记录自己下半年写题目的记录.题目来自书或者网站. 练习(一)的地址: https://blog.csdn.net/qq_41358574/article/details/117098620?ops_r ...

  6. 【练习】2021下半年数据结构刷题笔记和总结 (一)(图和动态规划)

    文章目录 1.编程将一个字符串中所有空格替换为"%20" 2.定两个字符串,判断一个字符串是否是另一个字符串的排列 3.求一个房间内有数个钩子,给定一定长度的绳索,要把所有的钩子用 ...

  7. 如何判断链表中是否存在环?Floyd判圈算法 leetcode刷题笔记 142. 环形链表 II

    这道题使用了floyd判圈算法,所以先讲解floyd算法的原理和实现,最后在附加上第142题的代码. floyd算法: 一.用途: 可以在有限状态机.迭代函数或者链表上判断是否存在环,求出该环的起点与 ...

  8. sqlzoo刷题笔记-02 | SUM and COUNT

    网址:https://sqlzoo.net/wiki/SUM_and_COUNT 1.Show the total population of the world. 显示世界总人口数. SELECT ...

  9. 一夜登顶GitHub!字节内网数据结构与算法刷题笔记,看完直呼卧槽

    网络上流传着一句段子"程序员两条腿,一条是算法,一条是英文,想跑的更远,这两条腿都不能弱".英文,我们暂且不谈,我们先来谈谈算法. 算法之难,在于将精巧的逻辑,通过合适的数据结构, ...

最新文章

  1. PriorityBlockingQueue详解
  2. matlab向量与x正方向的夹角_MIT—线性代数笔记25 对称矩阵和正定性
  3. 面试准备工作 -戈多编程
  4. 企业IM优劣势对比调查 各有特点
  5. ont维修使能工具_上海OTC机器人维修保养以及调试服务了解
  6. 比较常用的25条Excel技巧
  7. JMeter(十三)-代理服务器录制脚本
  8. 计算机二级省份,【计算机二级】这些省份发布报名时间!调整前的最后一次考试!...
  9. OptionRoom将在Bounce授权拍卖平台进行Polkadot IDO
  10. python安装pandas失败_详解pandas安装若干异常及解决方案总结
  11. 专访哈佛公共卫生学院院长胡里奥·弗兰克
  12. oracle通过正则验证香港、澳门、台湾的身份证和护照
  13. 5.1.6 假脱机技术(输入井、输出井、输入输出缓冲区、共享打印机原理分析)
  14. 【原创】年轻人接受指点,但不接受指指点点
  15. matlab双纵轴刻度覆盖问题,求助: matlab双纵轴换图问题
  16. 楼教主(楼天成)的ACM心路历程
  17. Blender_7_倒角
  18. 关于jacoco的学习
  19. EMV规范(七)——持卡人验证(CVM)一
  20. python中左对齐问题_[Python] print中的左右对齐问题

热门文章

  1. 用python画图需要什么插件_PIL(Python Imaging Library)-用Python画图
  2. 腾讯微服务框架-MSEC-部署 - 首个hello word服务
  3. linux电池充电阀值控制
  4. 拼多多API接口,item_get_app - 根据ID取商品详情原数据
  5. 国内chatGPT镜像
  6. 数据库-mysql(windows安装)
  7. Multi-University Training Contest 4
  8. 机器人鸣人是哪一集_博人传:佐良娜因爱开启二勾玉!迪帕是机器人,大蛇丸很怕鸣人?...
  9. 北京工业大学计算机试题,北京工业大学计算机学院 《数字逻辑》闭卷试题(A卷)...
  10. 额定功率、额定转速和额定转矩惯量和力矩