剑指offer刷题记录
2861
2021.01.28
2021.05.22
发布于 未知归属地

简介

记录下刷的题目思路,以及题目的总结,基本都是面试高频题目,面试pdd面过bfs,百度的面过字符串全排列

题号标题类型思路
3数组中重复的数字数组1刷和2刷都是用字典,题解有萝卜坑的思路非常巧妙
4二维数组的查找数组1刷和2刷都是用二分查找,时间复杂都是O(MlogN),题解有螃蟹步思路时间复杂度O(M+N)
5替换空格字符串\数组用python熟悉下api,C++空间复杂度上还可以再优化从O(N)到O(1)
6从尾到头打印链表链表\数组遍历链表保存到数组,然后用reverse或者用个temp把头尾调换下时间复杂度O(N),空间复杂度O(N)
7重建二叉树确定前序中的左子树的范围和右子树的范围,中序的左子树的范围和右子树的范围,递归即可,ps:同样的c++实现,使用算法自带库find和迭代速度快好多,pps:可以利用空间换时间,先把中序的节点对应的下标用字典保存下来,然后前序的根节点对应中序的根节点位置可以从字典获取
9用两个栈实现队列队列\栈栈1负责入栈,栈2负责出栈,栈2为空的时候就把栈1的元素push到栈2即可
10-1斐波那契数列找规律解题方法很多,dp或者递归,粗暴一点直接申请n+1内存dp下去,节省内存可以按照题意,直接定义三个变量fn,fn-1,fn-2然后计算即可,https://leetcode.cn/submissions/detail/144093951/
10-2青蛙跳台阶问题找规律同10-1 https://leetcode.cn/submissions/detail/144097948/
11旋转数组的最小数字二分查找注意数组可能有相同的值,PS:二分判断的时候if条件顺序改变会影响耗时 https://leetcode.cn/submissions/detail/144108336/
12矩阵中的路径bfs/dfs注意使用mask记录访问会超时,用个临时字符改变board,dfs完成后再复原https://leetcode.cn/submissions/detail/145286677/
13机器人的运动范围bfs/dfs先根据下标生成mask可到达矩阵,使用bfs从(0,0)开始遍历mask即可 https://leetcode.cn/submissions/detail/145294634/
14-1剪绳子dp1:用动态规划的方法,dp记录长度为i的绳子可以剪出的最好的乘机。dp[i] = max(dp[i], max(dp[i - j] * j, (i - j) * j)); j为当前剪去1到i-1的长度,i-j为剩下的不剪,dp[i-j]为剩下长度的最优剪。https://leetcode.cn/submissions/detail/145801646/。2:参考评论区的大佬直接用数学方法https://leetcode.cn/submissions/detail/145794940/
14-2剪绳子-2dppow不支持大数 https://leetcode.cn/submissions/detail/145806143/
15二进制中1的个数数组/位循环判断二进制串是否包含1 https://leetcode.cn/submissions/detail/145807473/
16数值的整数次方递归注意n为-2147483648取正会超范围。用long临时保存下,递归就可以https://leetcode.cn/submissions/detail/145860526/
17打印从1到最大的n位数大数/数组题目没有设计大数的用例,所以最简单的解法会ac,但是也要会写针对特别大的数字的解法(n=100)。先初始化‘000‘(n=3)模拟加法即可(001, 002, 003, 004),然后将字符串转为数字(题目要求int,一般大数问题直接返回vectorhttps://leetcode.cn/submissions/detail/145860526/
18删除链表的节点链表申请两个临时的节点,pre和prepre,也就是保存节点的前节点和前前节点。判断前节点的next的val是否和val相等。最后返回前前节点的next的next即可 https://leetcode.cn/submissions/detail/145992046/
21调整数组顺序使奇数位于偶数前面双指针/数组https://leetcode.cn/submissions/detail/146100227/
22链表中倒数第k个节点双指针/链表定义两个节点n1, n2, n1先走k步,然后n1,n2同时走,n1为空停止,n2就是倒数第k个节点 https://leetcode.cn/submissions/detail/146102919/
24反转链表双指针/链表https://leetcode.cn/submissions/detail/146104743/
25合并两个排序的链表链表不用额外申请节点,直接inplace的改变next指针即可 https://leetcode.cn/submissions/detail/146110438/
26树的子结构树皆可递归,两个树的节点的值相同的时候,判断各自的左子树和右子树的值是否相同。https://leetcode.cn/submissions/detail/146251803/
27二叉树的镜像树皆可递归,递归交换每个节点的左右子树即可。https://leetcode.cn/submissions/detail/146257430/
28对称的二叉树树皆可递归,递归判断根节点的左子树和右子树的值,以及左子树的左子树和右子树的右子树的值是否相同。https://leetcode.cn/submissions/detail/146260752/
29顺时针打印矩阵数组https://leetcode.cn/submissions/detail/146266645/
30包含min函数的栈使用两个栈,一个栈s1保存push的数据,一个栈s2保存非递增的数据(要push的值比栈上的top值要小的时候才push进去,s1栈上pop的值与s2栈的top值相同的时候才pop。https://leetcode.cn/submissions/detail/146266645/
31栈的压入、弹出序列使用栈模拟,pushed数据直接push进栈,当栈顶数据与poped相同时弹出,pushed遍历完判断栈是否为空。https://leetcode.cn/submissions/detail/146342940/
32-1从上到下打印二叉树树/bfshttps://leetcode.cn/submissions/detail/146610135/
32-2从上到下打印二叉树-2树/bfs用一个变量记录每层的个数,然后用bfs就行https://leetcode.cn/submissions/detail/146905023/
32-3从上到下打印二叉树-3树/bfs再加个reverse的flag初始化为false,当push_back一层后就置为true,然后把下一层的节点顺序reverse下即可,reverse再置为false。https://leetcode.cn/submissions/detail/147433681/
33二叉搜索树的后序遍历序列和7重建二叉树一样的思路,后序是左右根,先找到左子树和右子树的范围,遍历到第一个大于根节点的地方就是右子树开始的地方,然后递归划分,最后划分到只有一个节点return True,那么在什么情况下return False:也就是找到右子树开始的地方,接着往下遍历到根节点,只要有小于根节点就return False https://leetcode.cn/submissions/detail/147449346/
34二叉树中和为某一值的路径递归 https://leetcode.cn/submissions/detail/147770994/
35复杂链表的复制链表使用两个map(都是map<Node*, Node*>),一个保存old到new(复制新申请的内存)的映射dict1,一个保存new到old radom地址的映射dict2,新的链表的next指针在遍历的过程就赋值,新的节点random指针。使用dict2可以知道 old的地址,通过dict1知道new地址,这个就是新的节点的random指针的指向 https://leetcode.cn/submissions/detail/149003325/
36二叉搜索树与双向链表树/链表第一:二叉搜索树的中序遍历,正好是排序的链表,把处理链表的一些指针操作像打印链表放到inorder(root->left)和inorder(root->right)中间,https://leetcode.cn/problems/xu-lie-hua-er-cha-shu-lcof/
37序列化二叉树树/bfs第一可以去看时间分布的答案里超过100%(牛逼),第二,序列化和反序列化都用bfs思想 https://leetcode.cn/submissions/detail/150370545/
38字符串的全排列组合与排列题解:https://leetcode.cn/problems/zi-fu-chuan-de-pai-lie-lcof/solution/sheng-cheng-zu-he-dui-xiang-de-suan-fa-by-bugger-r/ https://leetcode.cn/submissions/detail/127179252/
39数组中出现次数超过一半的数字数组1刷后看题解的莫尔投票思路:https://leetcode.cn/submissions/detail/150733833/
40最小的k个数堆/快排堆:c++有make_heap的api建堆https://leetcode.cn/submissions/detail/150743747/ 快排思路:https://leetcode.cn/submissions/detail/151156621/
41数据流中的中位数利用两个大根堆,左堆保存更小的一半,右堆保存更大的一半的负数(小的数的取反后会再堆顶),https://leetcode.cn/submissions/detail/151183513/
42连续子数组的最大和动态规划https://leetcode.cn/submissions/detail/152124524/
431~n整数中1出现的次数规律把数字的位数分离出来,当前数字<0的时候,1的个数=高位数字x当前的base(百位还是千位还是个位),当前的数字等于1,1的个数=高位数字x当前的base+低位数字+1,当数字>1的时候,1的个数=(高位数字+1)x当前的base https://leetcode.cn/submissions/detail/152145566/ 题目很难理清思路,也很难想到思路,但是只要理清了,代码还是很好写的
44数字序列中的某一位的数字规律1刷毫无思路,看了解题区大佬的思路,佩服,过了2个月二刷,其实分为3步就可以了,第一:找到这个数有几位(是几百,几千,还是几万),确定的有多少位后,第二步是确定x位数中的第几个(确定是万数中的第几个数字),第三步是确定这个数字的中第某位数字(是万位,还是千位,还是百位)。https://leetcode.cn/submissions/detail/152275248/
45把数组排成最小的数数组先把数字转成字符串,然后按照字符串排序,但是这样,3和30两个数字会组成330并不是最小的,所以需要自定义排序函数,把两个字符串a,b,拼成ab和ba然后返回更小的就可以https://leetcode.cn/submissions/detail/152294552/
46把数字翻译成字符串递归/动态规划dfs(12258)=dfs(2258) + dfs(258); dfs(2258) = dfs(258) + dfs(58); dfs(258) = dfs(58) + dfs(8). dfs(58) = dfs(5)终止条件只有1个字符,dfs(58)=1, dfs(258)=1 + 1=2, dfs(2258)=2+1=3, dfs(12258)=3+2=5。中间的dfs(258)可以优化下保存下来,dfs(2258)和dfs(12258)都用到.https://leetcode.cn/submissions/detail/153171986/
47礼物的最大值动态规划原地动态规划即可 https://leetcode.cn/submissions/detail/153183943/
48最长不含重复字符的子字符串数组/字符串注意重复的字符是否在未重复字符串的中间还是再两端,https://leetcode.cn/submissions/detail/153578456/
49丑数动态规划k神的思路,使用三个索引a,b,c,求得2a,3b,5c最小的值,然后最小值对应的索引+1.返回dp[n-1];刷题的时候尽量用栈数组,vector数组更耗时 https://leetcode.cn/submissions/detail/154055063/
50第一个只出现一次的字符数组用两个数组分别保存字符的出现的次数mask,以及字符的索引idx,然后遍历mask,找到mask中的次数等于1的字符对应的索引。返回最小的索引即可。https://leetcode.cn/submissions/detail/154066960/
51数组中的逆序对归并排序先写个归并排序,然后再判断两个数字大小的时候计数下逆序对,ex:[5,7], [3,4]两部分,i=0,num1=5, j=0, num2=3。这时的逆序对+=(左边数组的右边界-左边数组当前数字的下标)=2.也就是(5>3, 7>3)。然后j++, (5>4, 7>4) https://leetcode.cn/submissions/detail/154559009/
52两个链表的第一个公共节点链表方法很多,方法1:可以先算法两个链表的长度,然后让长的链表先走n步(n为两个链表的差值),然后让两个链表同时走, 方法2:a,b链表同时走,某个链表为空的时候,遍历另一个链表的头节点,继续往下走(挺巧妙的) https://leetcode.cn/submissions/detail/154630943/
53-1在排序数组中查找数字二分查找一般有排序就是二分法,最原始的方法就是写两个二分,查找左边界和右边界。优化:把target的值+1,然后也变成查找左边界。https://leetcode.cn/submissions/detail/154879604/
53-20~n-1中缺失的数字二分查找排好序的数组 https://leetcode.cn/submissions/detail/155611860/
54二叉搜索树的第K大节点树/递归https://leetcode.cn/submissions/detail/155643380/
55-1二叉树的深度树/递归https://leetcode.cn/submissions/detail/156454329/
55-2平衡二叉树树/递归https://leetcode.cn/submissions/detail/156471720/
56-1数组中数字出现的次数二刷也没有思路
56-2数组中数字出现的次数 II数组统计二进制位数上的数字出现的次数,出现3次的话,该位对3取余则为0。https://leetcode.cn/submissions/detail/156939869/
57和为s的两个数字双指针https://leetcode.cn/submissions/detail/156939869/
57-2和为s的连续正数序列数组https://leetcode.cn/submissions/detail/157423803/
58-1翻转单词顺序字符串https://leetcode.cn/submissions/detail/157435192/
58-2左旋转字符串字符串https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
59-1滑动窗口的最大值单调队列https://leetcode.cn/submissions/detail/157975584/
59-2队列的最大值单调队列https://leetcode.cn/submissions/detail/158957693/
60n个骰子的点数递归https://leetcode.cn/submissions/detail/160751960/
61扑克牌中的顺子数组https://leetcode.cn/submissions/detail/161477518/
62圆圈中最后剩下的数字递归方法1:用列表模拟,动态调整列表,方法2:从活着的人的id往前推(amazing)
63股票的最大利润动态规划https://leetcode.cn/submissions/detail/162745479/
64求1+2+…+n递归&逻辑运算巧妙的用到与的运算,妈的这种题,不刷到死也想不出来,https://leetcode.cn/submissions/detail/161482149/
65不用加减乘除做加法逻辑运算用到与和异或运算,https://leetcode.cn/submissions/detail/166464038/
66构建乘积数组数组构建前缀乘和后缀乘数组,然后遍历相乘 https://leetcode.cn/submissions/detail/166481344/
67把字符串转换成整数字符串编译器分析token的感觉,注意下INT_MAX和INT_MIN的情况即可 https://leetcode.cn/submissions/detail/166509636/
68二叉搜索树的最近公共祖先树/递归用递归思路就比较简单,搜索树左小右大情况判断,然后递归左子树或者右子树
69二叉树的最近公共祖先dfs/bfshttps://leetcode.cn/submissions/detail/172276604/
评论 (0)