剑指offer&top 100归类

哈希

简单的

两数之和【两数之和: 一遍哈希/三数之和:排序+双指针/四数之和:排序+三数之和
字母异位词分组
最长连续序列【以当前为起点,不断尝试大于,小于的连续数】

双指针

简单的

移动零
盛最多水的容器【将 对应的数字较小的那个指针 往 另一个指针 的方向移动一个位置,就表示我们认为 这个指针不可能再作为容器的边界了】
三数之和【两数之和: 一遍哈希/三数之和:排序+双指针/四数之和:排序+三数之和

中等的

接雨水【左指针获得左边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 小的数

  1. 使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。时间复杂度是 O(m+n),空间复杂度是 O(m+n)
  2. 不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 0 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。时间复杂度是 O(m+n),空间复杂度是 O(1)
  3. 二分查找这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1,比较A[k/2−1] 和 B[k/2−1],一次可以排除一部分时间复杂度:O(log (m+n)),空间复杂度:O(1)。
  4. 数组划分。
    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-9
pow(10,k-1)*k,直到N小于0

面试题45:把数组排成最小的数

对于给定的2个数,a和b。如何确定两者之间的排序策略呢?我们可以发现这两者的排列为:ab,ba。我们最终目的是找到字典序最小的那个排列,所以我们肯定应该保持这种关系,从而决定是否交换顺序:

  1. 当ab < ba, a排在b的左边
  2. 当ab > ba, b排在a的左边
  3. 当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:股票的最大利润
当天卖,递归得到结果
求最值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值