----刷题总结

数据结构顺序:1数组 2链表3栈 4队列 5树 6图
方法:
图的方法:1.深度优先 2.广度优先 3.拓扑排序(有向是否有环) 4.并查集(多个组的查询和合并,也可用来做无向是否构成环) 5.染色法 6.狄杰斯特拉算法

栈是经常使用到辅助栈的,最经常用到的方法是单调栈方法(经常进栈的是序号而不是值,原理是找出左边的第一个比栈顶值大或小的值),栈问题尤其需要注意到。
(1)
https://leetcode.cn/problems/remove-duplicate-letters/solutions/290200/yi-zhao-chi-bian-li-kou-si-dao-ti-ma-ma-zai-ye-b-4/

(2)查询一个字符是否在字符串中出现过,不用用循环去一个个对比,直接if(a.find(b)<a.size())查询在a中是否有b的存在。是algorithm下的因此返回的是迭代器
vector 的 find 函数返回的是迭代器,如果在vector下查找的话用find(a.begin(),a.end(),b)!=a.end();
(1)链表方法(1)快慢链 (2)链表闭环在开环 (3)递归
1.可以用vector构建链表(ListNode),如vector<ListNode*>a={head},a是head的vector容器构建。而head->next等同于a.back()->next,head->val(head的值)等同于head.back().
2.在链表中经常要出现使用哑结点的情况,是在head链表头结点也可能会被删除,使用ListNode* newhead=new ListNode(0,head)将newhead指定为head并且有一个头结点。
3.构造无序哈希表,用unordered_map<ListNode*,num> a或unordered_set<ListNode*> a;可以用if(a(head))来判定是否在head链表里存在一个序列。
4.for循环中的迭代器;for(set::iterator it=a.begin();it!=a.end();it++)
定义时的迭代器set a::iterator it;
注意时STL中的map是it.first和it.second分别指键和值。
(5)指定了a字符串nullptr了,之后就不能再加值了,如string anullptr;a+=‘b’是错的,想要可以加的话定义string a=””;
2.栈
(1)peek()函数是返回栈顶元素不删除该元素,pop返回栈顶元素并删除。
(2)容器在 C++11 中对于添加元素除了常见的 insert 或者 pusb_back/push_front 之外还提供一个新的方法叫做 emplace。
(3)求下一个更大或更小元素类型的用到单调栈,单调栈就是栈里面的数据单调递增或递减,如[8,4,6,2,3]中找寻8后面最近小于元素是4,而2和3没有。此时需要的是从数组后面开始遍历,并进行入栈。
(4)vector中的acc[i],可以用acc.at(i)替代,at函数更好是因为不会访问过界元素,如for(int i=0;i<n;i++){a=acc[i-1]}就存在访问acc[-1]的情况用at就不会。
(5)atoi函数将字符串型转换为整形。和c_str()一起使用,c_str()将字符串变为整型。使用头文件include,如int a=atoi(b.c_str())(注意只能是string类型的,且只能是8字符串装化成8,而n这些字母的化转化的话为0,char型的话直接就a-‘0’)
(6)INT_MAX表示的是最大值,是2的31次方。还有INT_MIN是表示最小值,带#include<limits.h>。
(7)isdight函数,判断是否是十进制数字,头文件是ctype.h,如if(!isdight(a))(只检查是否为0到9)
(8)vector中的二维数组vector<vector > a;第一维大小m=a.size(),第二维是n=a[0].size();命名一个为0的数组,vector<vector > left(m,vector(n,0));
(9)处理逆波兰式用到栈的话可以用正负符号击穿括号方法,很便捷很快。如计算1+(2+3+4)-5的值时用栈就可以不将1,2,3,4,5,+,-这样的符号入栈而是将1和-1入栈,根据栈顶是1还是-1而计算。

(10) int[] count = new int[2]可以相当于是一个二维数组,他是计算count[0]和count[1]数量的,可以count[0]++和count[1]++;(很少见)
(11)一般情况下能用bfs就能用dfs,但是层序遍历和最短路径的话只能用bfs。具体见https://leetcode.cn/problems/binary-tree-level-order-traversal/solutions/244853/bfs-de-shi-yong-chang-jing-zong-jie-ceng-xu-bian-l/。注意层序遍历要求得到的是一个二维数组。(层序遍历和最短路径(是一棵树上一个结点到另一个结点的最短路径)算法时只有BFS能做到,DFS做不到)
(12)以后可能会遇到岛屿问题,这时候用dfs去做进行遍历是很好的。
(13)在vector中定义的二维数组都是动态的数组,因此每行的元素个数都是不同的,ve.push_back(vector());用来区分每行,如
就是在3和20遍历后用到了该代码。
(14)reverse函数是反转vector容器的函数,用法是reverse(a.begin(),a.end())
(15)ctrl+k+f是代码自动对齐。
(16)graphics.h是vsc里的图形库,可以接口图片。conio.h是可以用的热键库。具体见推箱子项目,使用用法见C:\Users\x’d’q\source\repos\easyX基本操作\easyX基本操作。
(17)简历的项目点上的描述成多个时间短,都有阶段性的高质量的开源项目。(如大一做了什么,大二做了什么,最好做成开源,产品级的项目输出,记得要高质量,不是什么俄罗斯方块之类的,给hr的印象:技术经验很长,而且有高质量的产出。西西老师(微信上)上面有付费的求职视频,里面有项目可以用可以学,以后那有没有机会吧。)

(18)回溯是递归的副产品,只要有递归就会有回溯,所以回溯法也经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都是用了递归。
回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下。是一条路一直走下去,直到走不通了在回溯到上一条路上。
(19)并查集是支持合并和查询的数据结构,其一般使用方法

(20)了解opencv,openjl,MTC,QT,duilib。
(21)防止控制台闪退方法有两种一种是system(“pause”),另一种是getchar();
(22)计算机的实现。

(23)实现判断图中是否有环很好的方法是拓扑排序。
(24)iota函数是用来批量递增vector的,如iota(a.bengin(),a.end(),1)是vector的a从1一直递增
(25)染色法判定二分图
(26)unordered_set是无序集,一般用来做检查,元素在容器中不能被修改,但是它们可以被插入和删除。
(27)vector中的back函数是返回最后一个数;
(28)但是map容器中的按键值排序和不允许由重复的元素,现在,我们可以利用
vector<pair<int,int> >来实现一对一,但其没有排序可以允许有重复的元素。Map是也是一对一,一般用在排序上。
(29)greater 一般用在sort和map的定义上,表示从大到小,如map<int,int,greater>表示定义一对一的map并从大到小排序。Sort(a.begin(),a.end(),greater<>)表示sort从大到小排序。
(30)to_string函数是将数字型转为string型。itoa也是同样作用,atoi是将int变为string(不过后面两种不好用)
(31)用stringstream将整形转化为字符串,头文件是,

S<<a是将a输入进入到steam流中,而s>>sa是将a的值变为sa输出了,或者其他的方法
定义string sm=s.str(),将a值赋给了sm,str(“”)是将steam清空,是必须的
(32)

(33)push_front是插入到前面,但是由于vector是数组就不可以在前面再创建出空间不适用与vector,可以用于list,而vector插入前面的方法是使用insert,insert可以再任意位置插入元素。与之相反的是erase可以在任意位置删除元素
(34)unordered_set的用法函数有特别之处

主要集中插入用的是insert。
(35)vector<vector> a;进行换行时使用a.push_back(vector ());
插入到第一维是a.back().push_back(m);对第一维进行多元素添加时用a.push_back({m,n}),而不是a.push_back([m,n]);对第一维的第二个元素使用方法是a.[0][1],还有中不指定第几维的是a.back()[1];
(36)c.str是将c++的string类型转换为C语言的字符串类型,最好不要直接赋值,而是使用strcpy进行赋值。
(37)arr.at(n)与arr[n]的含义一样,返回arr中第n个元素,唯一的区别在于at()函数比[]运算符更安全
因为at()不会去访问越界的元素
(38)nsigned int 是无符号整数类型,只能表示非负数(包括零)。它的范围通常是从 0 到 4,294,967,29
(32位系统)或从 0 到 18,446,744,073,709,551,615(64位系统)。Int是32位类型
(39)可以写queue<pair<int,int>> a;pair是一个对组,可以作为map的一组元素,但是pair可以有相同的
元素
(40)function函数是c++11的特性,头文件是#include,是将具有相同调用形
式的不同类型可调用对象进行类型统一。
(41)push_back和emplace_back的区别

emplace_back好用多了,而且在加入类的时候,push_back会调用拷贝构造函数
(42)

move告诉编译器我们有一个左值,但我们希望像一个右值一样处理它。注意:调用move
意味着承诺:除了对rr1赋值和销毁它以外,我们不再使用它。在调用move之后,我们不
能对移后源对象的值做任何假设。
对于move的名字冲突相比其他标准库函数的冲突频繁的多。于是我们在调用move函数时,
是使用std::move而不是move。
(43)字典树又叫前缀树:

(44)在vs中scanf已经被scanf_s所替代,scanf_s多了一个加字节数,记住是字节数而
是字符串长度,scanf_s(“%s”,str,sizeof(str));只能用sizeof函数而不是strlen函数。注意:
while (getchar() != ‘\n’);可能用完后用这个来清理缓冲区。memset(buff, 0,
sizeof(buff));也是用的字节数。
(45)sprintf_s是sprintf的安全版本,作用是一样的,是把格式化的数据写入某个字符串,如:
sprintf_s(name, sizeof(name), “res/zhiwu/%d/%d.png”, i, j + 1);是将 res/zhiwu/%d/%d.png
赋给name。
(46)>>是右移运算符,如a+b>>1是将a和b的结果右移一位,注意是得到a+b后转换为二进制再
右移一位,相当于a+b/2;<<相当于左移1乘2.
**(47)很需要注意的一个知识点,字符的比较什么时候用到strcmp什么时候用==。C 风格字符串
(字符数组)用到strcmp,C 风格字符串通常指的是以字符数组的形式表示的字符串,是C语言的表示方法,以空字符‘\0’结尾,而且strcmp比较时(相等返回0)里面的字符要类型一致都是都是指向字符数组(C 风格字符串)的指针。如果是c++中的string类型的话就可以直接用==比较
(48)isalpha(a)判断a是不是字符,是则返回1,与之对应的是isdigit
(49)堆排序是面试经常用到的,要学会自己构建一个堆
(50)accumulate函数是计算累加值,如accumulate(a.begin(),a.end(),0)是从a一直累加到最后到0里
(51)substr函数作用是提取字符串的子串的长度,如result = str.substr(7, 5);是从str第七个字符开始提取五个长度。
(52)epoll

(53)sizeof(evs) 是计算evs所占的字节数,而sizeof(evs)/sizeof(struct *)是用一个所占的字节数除以一个元素所占的字节数得到的是一共多少个元素数
(54)在#include<stdio.h>中有个perror函数,直接用就是perror(“listen”)在网络编程中常用.
(55)给文件写进去是ofstream,读的话是instream直接使用就是定义一个流,ofstream outfile; outfile<<abc;或instream infile; infile>>abc;
(56)a.str()是将a转换成c++的字符串,而a.c_str()是将a转换成C语言的字符串,用在sscanf(a.c_str(),“姓名:%s”,name)是因为sscanf是C语言的用法,得先将其转为C语言字符串,后匹配后面的格式。
(57)在写系统时会遇到对齐,控制宽度的大小,如cout<<setw(3)<<left<<a;就是左对齐、输出3个字符大小的a,也可以改右对齐,记得头文件是#include;
(58)eof是判断是否输入结束的,如输入的话是if(cin.eof())这是输入结束了,在文件的输入中也是一样,用到stream.eof();
(59)在文件读取的流的头文件是#include,读的是ifstream,写的是ifstream
在重载运算符中对<<和>>重载的时候分别使用ostream和istream
(60)一次读入一行的操作方法,string s;while(getline(cin,s)){};cin是遇见空白符为止,getline是遇见换行符为止
(61)int
row[4]是一个包含 4 个指针的数组,每个指针都指向一个整型值,int(*row)[4]是一个指针,指向一个包含 4 个整型元素的数组.
(62)在类中const函数只可以调用const函数,而非const函数可以调用const函数和非const函数,静态函数也是一样只能调用静态函数和静态变量,非静态变量也可以调用静态变量,而且静态变量不依赖于类的对象,它可以直接通过类作用域::加静态函数的方法使用。
(63)正则表达式的使用,用于邮箱的验证

(64)

(git强制覆盖写入是将最后一步改成
git remote add origin https://github.com/username/repository.git和
git push origin master --force(master可以变为你要覆盖写入的分支名)

(65)位运算符>>1表示操作数右移一位,也就是除以2,如8>>1就是4
(66)vector容器里面可以添加函数,使用函数指针添加,如vector<int()(int,int)> a;
A.push_back(add);vector里面定义了一个函数指针且只只能添加返回值为int,两个实参为int型的函数。使用add就可以用a[0](2,3);
(67)substr是string里的函数,从字符串中提取子字符串,std::string substr (size_t pos, size_t len) const。pos 是要提取子字符串的起始位置(从0开始计数),len 是要提取的子字符串的长度。
(68)static_cast是不能将试听类型转换为整数和浮点数之类的,这时候就得用stoi或stof
(69)push_back()只能接受一个参数并传入到容器的末尾,在有的时候是vector<pair<string,int>) vec;要传入一个pair对象就不能vec.push_back(str,i)只能将其创建一个pair对象传进去,如vec.push_back(pair<string,int>(str,int))或者是vec.push_back(make_pair(str,int)),make_pair函数或列表初始化,将两个值封装成一个pair对象
(70)map没有push_back函数,只能用insert插入或者[]
(71)const在函数里的用法基本有三种:
1.void fun(const int& a)a不能被修改
2.const int fun(int& a)函数的返回值不能被修改,且只能复制给加const修饰的同类型int值。
3.int fun(int& a) const函数的数据成员不能被修改,且数据成员不能调用非const成员函数。
(72)p =(int
) malloc(sizeof(int) * 10);是使用malloc的用法,前面不加(int*)的话返回的是void*,
malloc一般和free一起,new和delete一起,但是在类中都使用new的原因就是因为可以调用析构和构造函数
(73)在很多时候strcpy的使用会认为是不安全的,因为没有对缓冲区大小进行检查,可能导致缓冲区溢出,在c++里会用到安全的strcpy也就是strcpy_s()但是strcpy_s需要传入三个参数,中间需加个缓冲区大小,就是strcpy_s(a,6,“hello”);同时strcmp和strcat都有安全考虑的升级成strcmp_s和strcat_s,同时sprinttf这种用于格式化的函数也有升级成sprintf_s,在中间第二个参数设置缓冲区的大小。
(74)内存分配的三种方式:
1.静态存储区域分配,在编译期就分配好了,程序运行期间都存在,如全局变量
2.在栈上创建,在执行函数是,函数里局部变量的内存都是在栈上创建,函数结束时栈内存自动释放
3.堆上分创建,在堆上的都是动态分配内存,用malloc和new申请的任意多少内存,free和delete时释放,生存期我们自己决定

(75)const char* 变为string方法是直接const char* ch=“abc”;string str=string(ch);
string转换为const char*是用到c_str()
(76)无符号类型的整数进行运算的时候得注意,如果是一个unsigned int类型和int类型进行运算时,所有的int型都会自动转换为unsigned int类型,因此int型如果时一个负数如-20就是10010100会变为一个很大的正整数。
(77)struct类型时可以继承类的,如class a;可以做到struct b:a;而且类的默认成员访问权限和默认继承方式是私有继承,而struct的默认继承方式是共有继承。
(78)类的临时对象一般两种情况产生,(1)传入一个类实例对象的参数(2)返回一个类的实例对象,这两种情况都会生成一个临时的对象,会调用析构函数和构造函数,但是(2)情况调用的构造函数是复值构造函数,都是调用析构函数。
(79)c++的HANDLE句柄其实翻译的不好,翻译成抽屉更好,将操作系统比作一个盒子,handle就是抽屉能从其里面取出数据。

  • 32
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值