哈希
简单的
两数之和【两数之和: 一遍哈希/三数之和:排序+双指针/四数之和:排序+三数之和】
字母异位词分组
最长连续序列【以当前为起点,不断尝试大于,小于的连续数】
双指针
简单的
移动零
盛最多水的容器【将 对应的数字较小的那个指针 往 另一个指针 的方向移动一个位置,就表示我们认为 这个指针不可能再作为容器的边界了】
三数之和【两数之和: 一遍哈希/三数之和:排序+双指针/四数之和:排序+三数之和】中等的
接雨水【左指针获得左边max, 右指针获得右边max, 取最小得height】
面试题21:调整数组顺序使奇数位于偶数前面
双指针。左指针找偶数,右指针找奇数。调换
滑动窗口
简单的
无重复字符的最长子串【hash维护子串的信息】
找到字符串中所有字母异位词【hash维护diff的信息】
子串
简单的
和为 K 的子数组
滑动窗口最大值
最小覆盖子串
普通数组
简单的
最大子数组和
合并区间
轮转数组
除自身以外数组的乘积
缺失的第一个正数
中等的
面试题3:数组中重复的数字
面试题56:数组中数字出现的次数
面试题39:数组中出现次数超过一半的数字
面试题3:数组中重复的数字
数组长度为n,数字0到n-1。 不知道有几个数字重复。不知道数字重复几次。找出数组中任意一个重复的数字思路:
数组存储:对应数字的次数,第i位代表i的次数
哈希表存储:
题目一:找出数组中重复的数字
题目二:不修改数组找出重复的数字
面试题56:数组中数字出现的次数
题目一:数组中只出现一次的两个数字
遍历两遍。hash第一次加key,第二次删key
题目二:数组中唯一只出现一次的数字,其他出现两次
异或运算
面试题39:数组中出现次数超过一半的数字
基于Partition函数的O(n)算法
基于投票的
面试题51:数组中的逆序对
逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量;
归并排序
面试题53:在排序数组中查找数字
题目一:数字在排序数组中出现的次数
二分查找
题目二:0到n-1中缺失的数字
//利用求和公式
题目三:数组中数值和下标相等的元素
题目57:和为s的数字
题目一:和为S的两个数字,是否有
直接遍历一遍hash
题目二:和为S的连续正数序列,哪些
双指针。left 到right的数组和
面试题61:扑克牌的顺子
0代表大王小王,可以替换任意数字
排序,计算0的个数
如果数字重复,不是顺子
如果缺口数字大于0的个数,不是顺子
面试题66:构建乘积数组
两遍遍历,一遍正向,一遍反向。得到乘积
矩阵
简单的
矩阵置零
螺旋矩阵
旋转图像
搜索二维矩阵 II
面试题4:二维数组中的查找
左下或者右上搜索
面试题29:顺时针打印矩阵
四个方向依次判断,每个方向完后判断是不是需要停止
链表
简单的
相交链表简单:判断两个链表是否相交,以及相交的入口节点
反转链表简单:将链表进行反转
回文链表简单:判断链表是否是回文
环形链表简单:判断链表是否有环
合并两个有序链表简单:给定两个有序链表,进行合并
两数相加中等:逆序表示两个数字,求加法
删除链表的倒数第 N 个结点::::::头结点dummy,快慢指针fast先走N-1个,两个指针一起走,返回slow
两两交换链表中的节点中等:1 2 3 4 —》2 1 4 3
K 个一组翻转链表困难:上面的2–〉k
合并 K 个升序链表:困难
难的
环形链表 II中等:判断链表的环入口:::::快慢指针,相交之后。一个从初始节点走,一个从当前走。
随机链表的复制:难点:随机指针复制::::::先复制,插入,再复制节点,再输出
排序链表
LRU 缓存
面试题6:从尾到头打印链表
栈的概念 / 递归实现 / 放入容器中反转实现
面试题18:删除链表的节点
题目一:在O(1)时间删除链表结点
题目二:删除链表中重复的节点
头结点dummy面试题23:链表中环的入口结点
面试题22:链表中倒数第k个节点
面试题52:两个链表的第一个公共结点
面试题24:反转链表
面试题25:合并两个排序的链表
面试题35:复杂链表的复刻
二叉树
简单的
二叉树的中序遍历
二叉树的最大深度
翻转二叉树
二叉树的层序遍历
将有序数组转换为二叉搜索树
二叉树的右视图
面试题27:二叉树的镜像:::::将其变换为源二叉树的镜像
面试题32:从上到下打印二叉树
题目一:不分行从上往下打印二叉树
题目二:分行从上往下打印二叉树
题目三:之字形打印二叉树
利用两个栈的辅助空间分别存储奇数偶数层的节点,然后打印输出。
或使用链表的辅助空间来实现,利用链表的反向迭实现逆序输出。
中等的
对称二叉树:::::::左子树左与右子树右,左子树右与右子树左,
面试题28:对称的二叉树::判断一颗二叉树是不是对称的
二叉树的直径:::::::::::::返回高度和最大直径
验证二叉搜索树::::::::::::给定start,end, 判断范围:checkStartEnd(self, root, start=None, end=None)
二叉树展开为链表
从前序与中序遍历序列构造二叉树::::::[前序中序和后序].::::::::::找到左右子树的分界即可
面试题7:重建二叉树
难的
二叉搜索树中第K小的元素
路径总和 II
二叉树的最近公共祖先
二叉树中的最大路径和
面试题8:请找出中序遍历顺序的下一个结点并且返回
树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
面试题26:树的子结构:判断B是不是A的子结构
判断两个树是不是相等
面试题33:二叉搜索树的后序遍历序列
右左中,倒序遍历
面试题34:二叉树中和为某一值的路径
树的根结点开始往下一直到叶结点所经过的结点形成一条路径
叶子节点时判断
面试题36:二叉搜索树与双向链表
将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中
面试题37:序列化二叉树
面试题54:二叉搜索树的第k个结点
中序遍历,第k大树
面试题55:二叉树的深度
题目一:二叉树的深度
左右子树的最大深度加一
题目二:平衡二叉树
返回最大深度,是否平衡
abs(left - right) > 1) ans = false;
面试题68:树中两个结点的最低公共祖先
root 为空 返回root = None
root为p或q,返回root
判断root.left 和 root.right递归
left && right,返回root
如果right为None, 返回left, 否则返回right
图论
简单的
岛屿数量中等
腐烂的橘子中等
中等的
课程表中等
实现 Trie (前缀树)
回溯
简单的
全排列
子集
电话号码的字母组合
组合总和
括号生成
单词搜索
分割回文串
N 皇后
面试题12:矩阵中的路径
判断在一个矩阵中是否存在一条包含某字符串所有字符的路径
回溯法,dfs面试题13:机器人的运动范围
回溯法,bfs
面试题38:数字排列
输入一组数字(可能包含重复数字),输出其所有的排列方式。
回溯,判断非重复
二分查找
简单的
搜索插入位置
搜索二维矩阵
在排序数组中查找元素的第一个和最后一个位置
搜索旋转排序数组
寻找旋转排序数组中的最小值
寻找两个正序数组的中位数
面试题11:旋转数组的最小数字
二分。如果每段中属于递增,那么可以不考虑此段
1 寻找两个正序数组的中位数
寻找两个有序数组中的第 k 小的数
- 使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。时间复杂度是 O(m+n),空间复杂度是 O(m+n)
- 不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 0 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。时间复杂度是 O(m+n),空间复杂度是 O(1)
- 二分查找这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1,比较A[k/2−1] 和 B[k/2−1],一次可以排除一部分时间复杂度:O(log (m+n)),空间复杂度:O(1)。
- 数组划分。
AB 都划分为左右两个部分,len(A)=m,len(B)=n。A从i处划分,B从j处划分
0≤i≤m,0≤j≤n。m<n,对于任意的 i∈[0,m],都有 j= (m+n+1)/2−i∈[0,n],那么我们在 [0,m] 的范围内枚举 i 并得到 j,就不需要额外的性质了。时间复杂度:O(log min(m,n))),空间复杂度:O(1)。
栈
简单的
有效的括号
最小栈
字符串解码
每日温度
柱状图中最大的矩形
面试题9:
用两个栈实现队列
栈1只进。栈2只出
栈2为空时,栈1倒入栈2面试题30:包含min函数的栈
辅助栈
面试题31:栈的压入、弹出序列
判断是不是弹出顺序
面试题59:滑动窗口的最大值
单调递减栈
每次取栈底,pop栈底
堆
简单的
数组中的第K个最大元素
前 K 个高频元素
数据流的中位数
面试题40:最小的k个数
大顶堆排序
面试题41:数据流中的中位数
奇数个数值,中间的数值。偶数个数值,中间两个数的平均值。
创建优先级队列维护大顶堆和小顶堆两个堆,并且小顶堆的值都大于大顶堆的值
具体思路:
1.本代码为了保证两个堆的尺寸差距最大为1,采用奇数个时候插到大根堆,偶数个插到小根堆。
2.当数据总数为偶数时,新加入的元素,应当进入小根堆(注意不是直接进入小根堆,而是经大根堆筛选后取大根堆中最大元素进入小根堆),要保证小根堆里面所有数都比大根堆的大。
3.当数据为奇数个时,按照相应的调整进入大根堆。
4.如果个数位奇数个,则大根堆堆顶为中位数,否则就是两个堆顶除以2.比如新加入三个,那么第一个在大,第二个在小,第三个可能在大。所以就是大根堆的堆顶。
贪心算法
简单的
买卖股票的最佳时机
跳跃游戏
跳跃游戏 II
划分字母区间
动态规划
简单的
爬楼梯
杨辉三角
打家劫舍
完全平方数
零钱兑换
单词拆分
最长递增子序列
乘积最大子数组
分割等和子集
最长有效括号
面试题10:斐波那契数列
面试题19:正则表达式匹配
动态规划为j == * dp[i][j] = dp[i-1][j-1]
面试题47:礼物的最大价值
面试题60:骰子的点数
掷n次骰子,n次骰子之和为s,打印s所有可能的值出现的概率
s最小为n,最大为6n
动态规划:dp[n][j]代表扔n次,和为j
dp[n][j] = dp[n-1][j-1] +…… + dp[n-1][j-6]面试题42:连续子数组的最大和
动态规划。dp[i]为当前数字时最大和
dp[i]= max(dp[i-1]+nums[i], nums[i]
多维动态规划
简单的
不同路径
最小路径和
最长回文子串
最长公共子序列
编辑距离
技巧
简单的
只出现一次的数字
多数元素
颜色分类
下一个排列
寻找重复数
数学
面试题14:剪绳子
3(n-3) > 2(n-2), n>5时,尽量剪3
面试题16:数值的整数次方
2的100次方
二分。奇偶分别讨论,递归
面试题43:从1到n整数中1出现的次数
依此类推,从 1 至 10^ i ,在它们的左数第二位(右数第 i 位)中,任意的 X 都出现了 10^(i-1) 次。
1、取第 i 位左边的数字(高位),乘以 10 ^(i−1) ,得到基础值 a 。
2、取第 i 位数字,计算修正值:
1、如果大于 X,则结果为 a+ 10 ^(i−1) 。
2、如果小于 X,则结果为 a 。
3、如果等 X,则取第 i 位右边(低位)数字,设为 b ,最后结果为 a+b+1 。
面试题44:数字序列中某一位的数字
01234567891011121314排列,求某一位的数字
0-9 共10个数字,每个数字提供一位
10-99 共90个数字,每个数字提供2位
100-999 共900个数字,每个数字提供3位
1000-9999 共9000个数字,每个数字提供4位
把最初的0取掉,每一轮增加的位数都是9*pow(10,k-1)k,其中k表示当前是第几轮(或者说该轮中的数字的位数,如第一轮1位数,第二轮是2位数)
每判断一轮n的值就变为N-9pow(10,k-1)*k,直到N小于0
面试题45:把数组排成最小的数
对于给定的2个数,a和b。如何确定两者之间的排序策略呢?我们可以发现这两者的排列为:ab,ba。我们最终目的是找到字典序最小的那个排列,所以我们肯定应该保持这种关系,从而决定是否交换顺序:
- 当ab < ba, a排在b的左边
- 当ab > ba, b排在a的左边
- 当ab = ba, 位置关系随意
快排来排序
面试题49:丑数
只包含质因子2、3和5的数称作丑数
queue q
i, j, k 分别为2,3,5的上一个数
面试题64:求1+2+…+n
数学方法
递归
面试题65:不用加减乘除做加法
异或,计算加法和进位
位运算
面试题15:二进制中1的个数
n&(n-1) 操作相当于把二进制表示中最右边的1变成0。所以只需要看看进行了多少次这样的操作即可
位运算,最低位判断0,1,
n&1, n>>1
二进制中0的个数
每次右移一位,判断是否是0即可
二进制中最高位0的个数
每次与最高位为1的二进制进行&操作。0x80000000的二进制是1000 0000 0000 0000 …共32位,最高位为1
字符串
面试题5:替换空格
从前向后记录数目
从后向前替换
面试题20:表示数值的字符串
正负符号只能出现在s[0]或者’e’/‘E’的后面。
小数点只能出现一次,且只能在标志位为’integer’的时候出现,出现后置标志位为’decimal’表示出现了小数点。
‘e’/‘E’只能出现一次,且前后都必须有数字出现,即必须有haddigit=True前提,满足条件后将标志位置为’e’,并且置had_digit=False,指示其后必须有数字。
如果是数字,则置had_digit=True。
面试题46:把数字翻译成字符串
动态规划,dp[i]表示当前数字翻译为字符串的内容
当前小于等于6 且上一个小于等于2,dp[i] = dp[i-2] , dp[i-1]
否则, dp[i-1]
面试题48:最长不含重复字符的子字符串
双指针。
先扩大右指针,找到满足要求的位置,
再左指针收缩不满足要求,重复1
面试题50:第一个只出现一次的字符
题目一:字符串中第一个只出现一次的字符
计算出现次数,输出只有一次的字符
题目二:字符流中第一个只出现一次的字符
“google", 读出"go"时,第一个只出现一次的字符是"g"。
unordered_map<char, int> count; 计算出现次数
queue q; 存储只出现一次数据
面试题58:翻转字符串
题目一:翻转单词顺序
I am a student. ----- >student. a am I
题目二:左旋转字符串
”abcXYZdef”, 循环左移3位后,即“XYZdefabc”
翻转左半边,翻转右半边,翻转整个
面试题67:把字符串转换成整数
数值为0或者字符串不是一个合法的数值则返回0.负数返回负数
去除空格
找到正负号
开始计算:如果不属于0到9,返回0
否则,计算*10 + cur
字符串的排列
回溯法
面试题62:圆圈中最后剩下的数字
约瑟夫环
面试题63:股票的最大利润
当天卖,递归得到结果
求最值