面试LeetCode算法题整理,按照出现的频率依次递减排序,题目类型包含:简单、中等、困难
CodeTop地址:点击跳转
备注:出现的频率会随时间变化而变化,具体以CodeTop出现频率为准,每个题目整理出题目、思路、代码三部分
1. 无重复字符的最长子串-中等
题目:
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度
思路:
滑动窗口
代码:
1 |
2. 反转链表-简单
题目:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表
思路:
方法一:迭代
方法二:递归
代码:
1 |
3. LRU缓存-中等
题目:
请你设计并实现一个满足LRU (最近最少使用) 缓存约束的数据结构
实现 LRUCache 类:
LRUCache(int capacity)以 正整数 作为容量capacity初始化 LRU 缓存int get(int key)如果关键字key存在于缓存中,则返回关键字的值,否则返回-1- void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行
思路:
哈希表 + 双向链表
代码:
1 |
4. 数组中的第K个最大元素-中等
题目:
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题
思路:
方法一:基于快速排序的选择方法
方法二:基于堆排序的选择方法
代码:
1 |
5. K个一组翻转链表-困难
题目:
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换
思路:
模拟
代码:
1 |
6. 三数之和-中等
题目:
给你一个整数数组nums ,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且j != k,同时还满足nums[i] + nums[j] + nums[k] == 0
请你返回所有和为 0 且不重复的三元组
注意:答案中不可以包含重复的三元组
思路:
排序 + 双指针
代码:
1 |
7. 最大子数组和-中等
题目:
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和
子数组 是数组中的一个连续部分
思路:
方法一:动态规划
方法二:分治
代码:
1 |
8. 排序数组-快排-中等
题目:
给你一个整数数组 nums,请你将该数组升序排列
思路:
通过划分将待排序的序列分成前后两部分,其中前一部分的数据都比后一部分的数据要小,然后再递归调用函数对两部分的序列分别进行快速排序
代码:
1 |
9. 合并两个有序链表-简单
题目:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的
思路:
方法一:递归
方法二:迭代
代码:
1 |
10. 两数之和-简单
题目:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现
你可以按任意顺序返回答案
思路:
方法一:暴力枚举
方法二:哈希表
代码:
1 |
11. 二叉树的层序遍历-中等
题目:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)
思路:
广度优先搜索
代码:
1 |
12. 搜索旋转排序数组-中等
题目:
整数数组 nums 按升序排列,数组中的值 互不相同
在传递给函数之前,nums在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7]在下标3处经旋转后可能变为[4,5,6,7,0,1,2]
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题
思路:
二分查找
代码:
1 |
13. 买卖股票的最佳时机-简单
题目:
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
思路:
方法一:暴力法
方法二:一次遍历
代码:
1 |
14. 有效的括号-简单
题目:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合
- 左括号必须以正确的顺序闭合
- 每个右括号都有一个对应的相同类型的左括号
思路:
栈
代码:
1 |
15. 岛屿数量-中等
题目:
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成
此外,你可以假设该网格的四条边均被水包围
思路:
方法一:深度优先搜索
方法二:广度优先搜索
方法三:并查集
代码:
1 |
16. 环形链表-简单
题目:
给你一个链表的头节点 head ,判断链表中是否有环
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况
如果链表中存在环 ,则返回 true 。 否则,返回 false
思路:
方法一:哈希表
方法二:快慢指针
代码:
1 |
17. 最长回文子串-中等
题目:
给你一个字符串 s,找到 s 中最长的回文子串
思路:
方法一:动态规划
方法二:中心扩展算法
方法三:Manacher 算法
代码:
1 |
18. 二叉树的锯齿形层序遍历-中等
题目:
给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)
思路:
广度优先遍历
代码:
1 |
19. 合并两个有序数组-简单
题目:
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n
思路:
方法一:直接合并后排序
方法二:双指针
方法三:逆向双指针
代码:
1 |
20. 二叉树的最近公共祖先-中等
题目:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且x 的深度尽可能大(一个节点也可以是它自己的祖先)”
思路:
方法一:递归
方法二:存储父节点
代码:
1 |
21. 全排列-中等
题目:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案
思路:
回溯
代码:
1 |
22. 相交链表-简单
题目:

思路:
方法一:哈希集合
方法二:双指针
代码:
1 |
23. 螺旋矩阵-中等
题目:
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素
思路:
方法一:模拟
方法二:按层模拟
代码:
1 |
24. 合并K个升序链表-困难
题目:
给你一个链表数组,每个链表都已经按升序排列
请你将所有链表合并到一个升序链表中,返回合并后的链表
思路:
方法一:顺序合并
方法二:分治合并
方法三:使用优先队列合并
代码:
1 |
25. 反转链表 II-中等
题目:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right的链表节点,返回 反转后的链表
思路:
方法一:穿针引线
方法二:一次遍历「穿针引线」反转链表(头插法)
代码:
1 |
26. 字符串相加-简单
题目:
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式
思路:
模拟
代码:
1 |
27. 环形链表 II-中等
题目:
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 *如果链表无环,则返回 null
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况
思路:
方法一:哈希表
方法二:快慢指针
代码:
1 |
28. 长递增子序列-中等
题目:
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列
思路:
方法一:动态规划
方法二:贪心 + 二分查找
代码:
1 |
29. 接雨水-困难
题目:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水
思路:
方法一:动态规划
方法二:单调栈
方法三:双指针
代码:
1 |
30. 二叉树中的最大路径和-困难
题目:
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点
路径和 是路径中各节点值的总和
给你一个二叉树的根节点 root ,返回其 最大路径和
思路:
递归
代码:
1 |
31. 重排链表-中等
题目:
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
1 | L0 → L1 → … → Ln - 1 → Ln |
请将其重新排列后变为:
1 | L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … |
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换
思路:
方法一:线性表
方法二:寻找链表中点 + 链表逆序 + 合并链表
代码:
1 |
32. 二叉树的中序遍历-简单
题目:
给定一个二叉树的根节点 root ,返回 它的 中序遍历
思路:
方法一:递归
方法二:迭代
方法三:Morris 中序遍历
代码:
1 |
33. 二分查找-简单
题目:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
思路:
二分查找
代码:
1 |
34. 编辑距离-困难
题目:
给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
思路:
动态规划
代码:
1 |
35. 用栈实现队列-简单
题目:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x)将元素 x 推到队列的末尾int pop()从队列的开头移除并返回元素int peek()返回队列开头的元素boolean empty()如果队列为空,返回true;否则,返回false
说明:
- 你 只能 使用标准的栈操作 —— 也就是只有
push to top,peek/pop from top,size, 和is empty操作是合法的 - 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可
思路:
双栈
代码:
1 |
36. 寻找两个正序数组的中位数-困难
题目:
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数
算法的时间复杂度应该为 O(log (m+n))
思路:
方法一:二分查找
方法二:划分数组
代码:
1 |
37. 二叉树的右视图-中等
题目:
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
38. 除链表的倒数第N个结点-中等
题目:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点
思路:
方法一:计算链表长度
方法二:栈
方法三:双指针
代码:
1 |
39. 爬楼梯-简单
题目:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢
思路:
方法一:动态规划
方法二:矩阵快速幂
方法三:通项公式
代码:
1 |
40. 合并区间-中等
题目:
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间
思路:
排序
代码:
1 |
41. 排序链表-中等
题目:
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表
思路:
方法一:自顶向下归并排序
方法二:自底向上归并排序
代码:
1 |
42. 删除排序链表中的重复元素 II-中等
题目:
给定一个已排序的链表的头head,删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表
思路:
一次遍历
代码:
1 |
43. 下一个排列-中等
题目:
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列
- 例如,
arr = [1,2,3],以下这些都可以视作arr的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1]
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)
- 例如,
arr = [1,2,3]的下一个排列是[1,3,2] - 类似地,
arr = [2,3,1]的下一个排列是[3,1,2] - 而
arr = [3,2,1]的下一个排列是[1,2,3],因为[3,2,1]不存在一个字典序更大的排列
给你一个整数数组 nums ,找出 nums 的下一个排列
必须原地修改,只允许使用额外常数空间
思路:
两遍扫描
代码:
1 |
44. x 的平方根 -简单
题目:
给你一个非负整数 x ,计算并返回 x 的 算术平方根
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 **舍去 **
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5
思路:
方法一:袖珍计算器算法
方法二:二分查找
方法三:牛顿迭代
代码:
1 |
45. 两数相加-中等
题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字
请你将两个数相加,并以相同形式返回一个表示和的链表
你可以假设除了数字 0 之外,这两个数都不会以 0 开头
思路:
模拟
代码:
1 |
46. 字符串转换整数 (atoi)-中等
题目:
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)
函数 myAtoi(string s) 的算法如下:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略
- 将前面步骤读入的这些数字转换为整数(即,”123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)
- 如果整数数超过 32 位有符号整数范围
[−231, 231 − 1],需要截断这个整数,使其保持在这个范围内。具体来说,小于−231的整数应该被固定为−231,大于231 − 1的整数应该被固定为231 − 1 - 返回整数作为最终结果
注意:
- 本题中的空白字符只包括空格字符
' ' - 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符
思路:
自动机
代码:
1 |
47. 最长公共子序列-中等
题目:
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串
- 例如,
"ace"是"abcde"的子序列,但"aec"不是"abcde"的子序列
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列
思路:
动态规划
代码:
1 |
48. 括号生成-中等
题目:
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合
思路:
方法一:暴力法
方法二:回溯法
方法三:按括号序列的长度递归
代码:
1 |
49. 滑动窗口最大值-困难
题目:
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k 个数字。滑动窗口每次只向右移动一位
返回 滑动窗口中的最大值
思路:
方法一:优先队列
方法二:单调队列
方法三:分块 + 预处理
代码:
1 |
50. 复原 IP 地址-中等
题目:
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔
- 例如:
"0.1.2.201"和"192.168.1.1"是 有效 IP 地址,但是"0.011.255.245"、"192.168.1.312"和"192.168@1.1"是 无效 IP 地址
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案
思路:
回溯
代码:
1 |
51. 缺失的第一个正数-困难
题目:
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案
思路:
方法一:哈希表
方法二:置换
代码:
1 |
52. 链表中倒数第k个节点-简单
题目:
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点
思路:
方法一:顺序查找
方法二:双指针
代码:
1 |
53. 从前序与中序遍历序列构造二叉树-中等
题目:
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点
思路:
方法一:递归
方法二:迭代
代码:
1 |
54. 比较版本号-中等
题目:
给你两个版本号 version1 和 version2 ,请你比较它们
版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号
比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1
返回规则如下:
- 如果
*version1* > *version2*返回1 - 如果
*version1* < *version2*返回-1 - 除此之外返回
0
思路:
方法一:字符串分割
方法二:双指针
代码:
1 |
55. 零钱兑换-中等
题目:
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1
你可以认为每种硬币的数量是无限的
思路:
方法一:记忆化搜索
方法二:动态规划
代码:
1 |
56. 最小覆盖子串-困难
题目:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
注意:
- 对于
t中重复字符,我们寻找的子字符串中该字符数量必须不少于t中该字符数量。 - 如果
s中存在这样的子串,我们保证它是唯一的答案
思路:
滑动窗口
代码:
1 |
57. 二叉树的前序遍历-简单
题目:
给你二叉树的根节点 root ,返回它节点值的 前序 遍历
思路:
方法一:递归
方法二:迭代
方法三:Morris 遍历
代码:
1 |
58. 反转字符串中的单词-中等
题目:
给你一个字符串 s ,请你反转字符串中 单词 的顺序
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格
思路:
方法一:使用语言特性
方法二:自行编写对应的函数
方法三:双端队列
代码:
1 |
59. 字符串相乘-中等
题目:
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数
思路:
方法一:做加法
方法二:做乘法
代码:
1 |
60. 最小栈-中等
题目:
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈
实现 MinStack 类:
MinStack()初始化堆栈对象void push(int val)将元素val推入堆栈void pop()删除堆栈顶部的元素int top()获取堆栈顶部的元素int getMin()获取堆栈中的最小元素
思路:
辅助栈
代码:
1 |
61. 平衡二叉树-简单
题目:
给定一个二叉树,判断它是否是高度平衡的二叉树
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1
思路:
方法一:自顶向下的递归
方法二:自底向上的递归
代码:
1 |
62. 子集-中等
题目:
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集
思路:
方法一:迭代法实现子集枚举
方法二:递归法实现子集枚举
代码:
1 |
63. 二叉树的最大深度-简单
题目:
给定一个二叉树,找出其最大深度
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数
说明: 叶子节点是指没有子节点的节点
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
64. 求根节点到叶节点数字之和-中等
题目:
给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字
每条从根节点到叶节点的路径都代表一个数字:
- 例如,从根节点到叶节点的路径
1 -> 2 -> 3表示数字123
计算从根节点到叶节点生成的 所有数字之和
叶节点 是指没有子节点的节点
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
65. 最长有效括号-困难
题目:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度
思路:
方法一:动态规划
方法二:栈
方法三:不需要额外的空间
代码:
1 |
66. 对称二叉树-简单
题目:
给你一个二叉树的根节点 root , 检查它是否轴对称
思路:
方法一:递归
方法二:迭代
代码:
1 |
67. 验证二叉搜索树-中等
题目:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数
- 节点的右子树只包含 大于 当前节点的数
- 所有左子树和右子树自身必须也是二叉搜索树
思路:
方法一: 递归
方法二:中序遍历
代码:
1 |
68. 最小路径和-中等
题目:
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小
说明:每次只能向下或者向右移动一步
思路:
动态规划
代码:
1 |
69. 二叉树的直径-简单
题目:
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点
思路:
深度优先搜索
代码:
1 |
70. 路径总和 II-中等
题目:
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径
叶子节点 是指没有子节点的节点
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
71. Rand7() 实现 Rand10()-简单
题目:
给定方法 rand7 可生成 [1,7] 范围内的均匀随机整数,试写一个方法 rand10 生成 [1,10] 范围内的均匀随机整数
你只能调用 rand7() 且不能调用其他方法。请不要使用系统的 Math.random() 方法
每个测试用例将有一个内部参数 n,即你实现的函数 rand10() 在测试时将被调用的次数。请注意,这不是传递给 rand10() 的参数
思路:
拒绝采样
代码:
1 |
72. 组合总和-中等
题目:
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的
对于给定的输入,保证和为 target 的不同组合数少于 150 个
思路:
搜索回溯
代码:
1 |
73. 旋转图像-中等
题目:
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度
你必须在原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像
思路:
方法一:使用辅助数组
方法二:原地旋转
方法三:用翻转代替旋转
代码:
1 |
74. 路径总和-简单
题目:
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false
叶子节点 是指没有子节点的节点
思路:
方法一:广度优先搜索
方法二:递归
代码:
1 |
75. 回文链表-简单
题目:
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false
思路:
方法一:将值复制到数组中后用双指针法
方法二:递归
方法三:快慢指针
代码:
1 |
76. 多数元素-简单
题目:
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素
你可以假设数组是非空的,并且给定的数组总是存在多数元素
思路:
方法一:哈希表
方法二:排序
方法三:随机化
方法四:分治
方法五:Boyer-Moore 投票算法
代码:
1 |
77. 最长重复子数组-中等
题目:
给两个整数数组 nums1 和 nums2 ,返回两个数组中 公共的 、长度最长的子数组的长度
思路:
方法一:动态规划
方法二:滑动窗口
方法三:二分查找 + 哈希
代码:
1 |
78. 最大正方形-中等
题目:
在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积
思路:
方法一:暴力法
方法二:动态规划
代码:
1 |
79. 字符串解码-中等
题目:
给定一个经过编码的字符串,返回它解码后的字符串
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入
思路:
方法一:栈操作
方法二:递归
代码:
1 |
80. 搜索二维矩阵 II-中等
题目:
编写一个高效的算法来搜索 *m* x *n* 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列
- 每列的元素从上到下升序排列
思路:
方法一:直接查找
方法二:二分查找
方法三:Z 字形查找
代码:
1 |
81. 翻转二叉树-简单
题目:
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点
思路:
递归
代码:
1 |
82. 在排序数组中查找元素的第一个和最后一个位置-中等
题目:
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置
如果数组中不存在目标值 target,返回 [-1, -1]
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题
思路:
二分查找
代码:
1 |
83. 最长公共前缀-简单
题目:
编写一个函数来查找字符串数组中的最长公共前缀
如果不存在公共前缀,返回空字符串 ""
思路:
方法一:横向扫描
方法二:纵向扫描
方法三:分治
方法四:二分查找
代码:
1 |
84. 寻找峰值-中等
题目:
峰值元素是指其值严格大于左右相邻值的元素
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可
你可以假设 nums[-1] = nums[n] = -∞
你必须实现时间复杂度为 O(log n) 的算法来解决此问题
思路:
方法一:寻找最大值
方法二:迭代爬坡
方法三:方法二的二分查找优化
代码:
1 |
85. 最长连续序列-中等
题目:
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度
请你设计并实现时间复杂度为 O(n) 的算法解决此问题
思路:
哈希表
代码:
1 |
86. 基本计算器 II-中等
题目:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值
整数除法仅保留整数部分
你可以假设给定的表达式总是有效的。所有中间结果将在 [-2^31, 2^31 - 1] 的范围内
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()
思路:
栈
代码:
1 |
87. 岛屿的最大面积-中等
题目:
给你一个大小为 m x n 的二进制矩阵 grid
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着
岛屿的面积是岛上值为 1 的单元格的数目
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0
思路:
方法一:深度优先搜索
方法二:深度优先搜索 + 栈
方法三:广度优先搜索
代码:
1 |
88. 删除排序链表中的重复元素-简单
题目:
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回已排序的链表
思路:
一次遍历
代码:
1 |
89. 不同路径-中等
题目:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )
问总共有多少条不同的路径?
思路:
方法一:动态规划
方法二:组合数学
代码:
1 |
90. 打家劫舍-中等
题目:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额
思路:
动态规划
代码:
1 |
91. 买卖股票的最佳时机 II-中等
题目:
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售
返回你能获得的 最大 利润
思路:
方法一:动态规划
方法二:贪心
代码:
1 |
92. 两两交换链表中的节点-中等
题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)
思路:
方法一:递归
方法二:迭代
代码:
1 |
93. 乘积最大子数组-中等
题目:
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积
测试用例的答案是一个 32-位 整数
子数组 是数组的连续子序列
思路:
动态规划
代码:
1 |
94. 移动零-简单
题目:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序
请注意 ,必须在不复制数组的情况下原地对数组进行操作
思路:
双指针
代码:
1 |
95. 二叉树最大宽度-中等
题目:
给你一棵二叉树的根节点 root ,返回树的 最大宽度
树的 最大宽度 是所有层中最大的 宽度
每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度
题目数据保证答案将会在 32 位 带符号整数范围内
思路:
方法一:广度优先搜索
方法二:深度优先搜索
代码:
1 |
96. 复制带随机指针的链表-中等
题目:
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点
例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y
返回复制链表的头节点
用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示Node.val的整数random_index:随机指针指向的节点索引(范围从0到n-1);如果不指向任何节点,则为null
你的代码 只 接受原链表的头节点 head 作为传入参数
思路:
方法一:回溯 + 哈希表
方法二:迭代 + 节点拆分
代码:
1 |
97. 排序数组-堆排序-中等
题目:
给你一个整数数组 nums,请你将该数组升序排列
思路:
先将待排序的序列建成大根堆,使得每个父节点的元素大于等于它的子节点
代码:
1 |
98. 寻找旋转排序数组中的最小值-中等
题目:
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
- 若旋转
4次,则可以得到[4,5,6,7,0,1,2] - 若旋转
7次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题
思路:
二分查找
代码:
1 |
99. 最大数-中等
题目:
给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数
注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数
思路:
排序
代码:
1 |
100. 二叉树的序列化与反序列化-困难
题目:
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构
思路:
方法一:深度优先搜索
方法二:括号表示编码 + 递归下降解码
代码:
1 |
101. 长度最小的子数组-中等
题目:
给定一个含有 n 个正整数的数组和一个正整数 target
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0
思路:
方法一:暴力法
方法二:前缀和 + 二分查找
方法三:滑动窗口
代码:
1 |
102. 单词拆分-中等
题目:
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用
思路:
动态规划
代码:
1 |
103. 验证IP地址-中等
题目:
给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 "IPv4" ;如果是有效的 IPv6 地址,返回 "IPv6" ;如果不是上述类型的 IP 地址,返回 "Neither"
有效的IPv4地址 是 “x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255 且 xi 不能包含 前导零。例如: “192.168.1.1” 、 “192.168.1.0” 为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00” 、 “192.168@1.1” 为无效IPv4地址
一个有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8” 的IP地址,其中:
1 <= xi.length <= 4xi是一个 十六进制字符串 ,可以包含数字、小写英文字母('a'到'f')和大写英文字母('A'到'F')- 在
xi中允许前导零
例如 "2001:0db8:85a3:0000:0000:8a2e:0370:7334" 和"2001:db8:85a3:0:0:8A2E:0370:7334" 是有效的 IPv6地址,而 "2001:0db8:85a3::8A2E:037j:7334" 和 "02001:0db8:85a3:0000:0000:8a2e:0370:7334" 是无效的 IPv6 地址
思路:
依次判断
代码:
1 |
104. 和为 K 的子数组-中等
题目:
给你一个整数数组 nums 和一个整数 k ,请你统计并返回该数组中和为 k 的连续子数组的个数
思路:
方法一:枚举
方法二:前缀和 + 哈希表优化
代码:
1 |
105. 只出现一次的数字-简单
题目:
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间
思路:
位运算
代码:
1 |
106. 用两个栈实现队列-简单
题目:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
思路:
双栈
代码:
1 |
107. 对角线遍历-中等
题目:
给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素
思路:
直接模拟
代码:
1 |
108. 移掉 K 位数字-中等
题目:
给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字
思路:
贪心 + 单调栈
代码:
1 |
109. 基本计算器-困难
题目:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()
思路:
括号展开 + 栈
代码:
1 |
110. 二叉搜索树与双向链表-中等
题目:
思路:
代码:
111. 排序数组-归并排序-中等
题目:
给你一个整数数组 nums,请你将该数组升序排列
思路:
利用了分治的思想来对序列进行排序
代码:
1 |
112. LFU 缓存-困难
题目:
请你为最不经常使用(LFU)缓存算法设计并实现数据结构
实现 LFUCache 类:
LFUCache(int capacity)- 用数据结构的容量capacity初始化对象int get(int key)- 如果键key存在于缓存中,则获取键的值,否则返回-1void put(int key, int value)- 如果键key已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量capacity时,则应该在插入新项之前,移除最不经常使用的项。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键
为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键
当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 get 或 put 操作,使用计数器的值将会递增
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行
思路:
方法一:哈希表 + 平衡二叉树
方法二:双哈希表
代码:
1 |
113. 每日温度-中等
题目:
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替
思路:
方法一:暴力
方法二:单调栈
代码:
1 |
114. 课程表-中等
题目:
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi
- 例如,先修课程对
[0, 1]表示:想要学习课程0,你需要先完成课程1
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false
思路:
方法一:深度优先搜索
方法二: 广度优先搜索
代码:
1 |
115. 排序奇升偶降链表-中等
题目:
字节跳动高频题
思路:
代码:
1 |
116. 二叉树的完全性检验-中等
题目:
给定一个二叉树的 root ,确定它是否是一个完全二叉树
在一个 完全二叉树 中,除了最后一个关卡外,所有关卡都是完全被填满的,并且最后一个关卡中的所有节点都是尽可能靠左的。它可以包含 1 到 2h 节点之间的最后一级 h
思路:
广度优先搜索
代码:
1 |
117. 检测循环依赖-中等
题目:
补充题
思路:
代码:
1 |
118. 二叉搜索树的第k大节点-简单
题目:
给定一棵二叉搜索树,请找出其中第 k 大的节点的值
思路:
代码:
1 |
119. 盛最多水的容器-中等
题目:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水
返回容器可以储存的最大水量
说明:你不能倾斜容器
思路:
双指针
代码:
1 |
120. 单词搜索-中等
题目:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用
思路:
回溯
代码:
1 |
121. 青蛙跳台阶问题-简单
题目:
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1
思路:
代码:
1 |
122. 组合总和 II-中等
题目:
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合
candidates 中的每个数字在每个组合中只能使用 一次
注意:解集不能包含重复的组合
思路:
回溯
代码:
1 |
123. 跳跃游戏-中等
题目:
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标
数组中的每个元素代表你在该位置可以跳跃的最大长度
判断你是否能够到达最后一个下标
思路:
贪心
代码:
1 |
124. 二叉树的后序遍历-简单
题目:
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历
思路:
方法一:递归
方法二:迭代
方法三:Morris 遍历
代码:
1 |
125. 数组中的逆序对-困难
题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数
思路:
方法一:归并排序
方法二:离散化树状数组
代码:
1 |
126. 螺旋矩阵 II-中等
题目:
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix
思路:
模拟
代码:
1 |
127. 搜索二维矩阵-中等
题目:
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
- 每行中的整数从左到右按升序排列
- 每行的第一个整数大于前一行的最后一个整数
思路:
方法一:两次二分查找
方法二:一次二分查找
代码:
1 |
128. 删除有序数组中的重复项-简单
题目:
给你一个 升序排列 的数组 nums ,请你原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果
将最终结果插入 nums 的前 k 个位置后返回 k
不要使用额外的空间,你必须在 原地修改输入数组 并在使用 O(1) 额外空间的条件下完成
思路:
双指针
代码:
1 |
129. 圆环回原点问题-中等
题目:
字节跳动高频题
思路:
代码:
1 |
130. 全排列 II-中等
题目:
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列
思路:
搜索回溯
代码:
1 |
131. 零钱兑换 II-中等
题目:
思路:
代码:
1 |
132. 斐波那契数列-简单
题目:
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
1 | F(0) = 0, F(1) = 1 |
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1
思路:
方法一:动态规划
方法二:矩阵快速幂
代码:
1 |
133. Pow(x, n)-中等
题目:
实现pow(x, n) ,即计算 x 的整数 n 次幂函数(即,x^n )
思路:
方法一:快速幂 + 递归
方法二:快速幂 + 迭代
代码:
1 |
134. 旋转链表-中等
题目:
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置
思路:
闭合为环
代码:
1 |
135. 删除二叉搜索树中的节点-中等
题目:
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用
一般来说,删除节点可分为两个步骤:
- 首先找到需要删除的节点
- 如果找到了,删除它
思路:
方法一:递归
方法二:迭代
代码:
1 |
136. 最小的k个数-简单
题目:
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4
思路:
方法一:排序
方法二:堆
方法三:快排思想
代码:
1 |
137. 卖股票的最佳时机 III-困难
题目:
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
思路:
动态规划
代码:
1 |
138. 整数反转-简单
题目:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0
假设环境不允许存储 64 位整数(有符号或无符号)
思路:
数学
代码:
1 |
139. 连续子数组的最大和-简单
题目:
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值
要求时间复杂度为O(n)
思路:
方法一:动态规划
方法二:分治
代码:
1 |
140. 整数组顺序使奇数位于偶数前面-简单
题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分
思路:
方法一:两次遍历
方法二:双指针 + 一次遍历
方法三:原地交换
代码:
1 |
141. 二叉搜索树中第K小的元素-中等
题目:
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)
思路:
方法一:中序遍历
方法二:记录子树的结点数
方法三:平衡二叉搜索树
代码:
1 |
142. 用队列实现栈-简单
题目:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)
实现 MyStack 类:
void push(int x)将元素 x 压入栈顶int pop()移除并返回栈顶元素int top()返回栈顶元素boolean empty()如果栈是空的,返回true;否则,返回false
注意:
- 你只能使用队列的基本操作 —— 也就是
push to back、peek/pop from front、size和is empty这些操作 - 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可
思路:
方法一:两个队列
方法二:一个队列
代码:
1 |
143. 字典序的第K小数字-困难
题目:
给定整数 n 和 k,返回 [1, n] 中字典序第 k 小的数字
思路:
字典树思想
代码:
1 |
144. 分发糖果-困难
题目:
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1个糖果 - 相邻两个孩子评分更高的孩子会获得更多的糖果
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目
思路:
方法一:两次遍历
方法二:常数空间遍历
代码:
1 |
145. 圆圈中最后剩下的数字-简单
题目:
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3
思路:
方法一:数学 + 递归
方法二:数学 + 迭代
代码:
1 |
146. 颜色分类-中等
题目:
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色
必须在不使用库的sort函数的情况下解决这个问题
思路:
方法一:单指针
方法二:双指针
方法三:双指针
代码:
1 |
147. 矩阵中的最长递增路径-困难
题目:
给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度
对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)
思路:
方法一:记忆化深度优先搜索
方法二:拓扑排序
代码:
1 |
148. 二维数组中的查找-中等
题目:
在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数
思路:
方法一:直接查找
方法二:二分查找
方法三:Z 字形查找
代码:
1 |
149. 奇偶链表-中等
题目:
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题
思路:
分离节点后合并
代码:
1 |
150. 解码方法-中等
题目:
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
1 | 'A' -> "1" |
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"11106" 可以映射为:
"AAJF",将消息分组为(1 1 10 6)"KJF",将消息分组为(11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6" 和 "06" 在映射中并不等价
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数
题目数据保证答案肯定是一个 32 位 的整数
思路:
动态规划
代码:
1 |
151. 另一棵树的子树-简单
题目:
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树
思路:
方法一:深度优先搜索暴力匹配
方法二:深度优先搜索序列上做串匹配
方法三:树哈希
代码:
1 |
152. 打乱数组-中等
题目:
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的
实现 Solution class:
Solution(int[] nums)使用整数数组nums初始化对象int[] reset()重设数组到它的初始状态并返回int[] shuffle()返回数组随机打乱后的结果
思路:
方法一:暴力
方法二:Fisher-Yates 洗牌算法
代码:
1 |
153. 验证回文串-简单
题目:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串
字母和数字都属于字母数字字符
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false
思路:
方法一:筛选 + 判断
方法二:在原字符串上直接判断
代码:
1 |
154. 回文数-简单
题目:
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数
- 例如,
121是回文,而123不是
思路:
反转一半数字
代码:
1 |
154. 轮转数组-中等
题目:
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数
思路:
方法一:使用额外的数组
方法二:环状替换
方法三:数组翻转
代码:
1 |
155. 跳跃游戏 II-中等
题目:
给你一个非负整数数组 nums ,你最初位于数组的第一个位置
数组中的每个元素代表你在该位置可以跳跃的最大长度
你的目标是使用最少的跳跃次数到达数组的最后一个位置
假设你总是可以到达数组的最后一个位置
思路:
方法一:反向查找出发位置
方法二:正向查找可到达的最大位置
代码:
1 |
157. 两数相加 II-中等
题目:
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表
你可以假设除了数字 0 之外,这两个数字都不会以零开头
思路:
栈
代码:
1 |
158. 二叉树的镜像-简单
题目:

思路:
递归
代码:
1 |
159. 寻找重复数-中等
题目:
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数
假设 nums 只有 一个重复的整数 ,返回 这个重复的数
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间
思路:
方法一:二分查找
方法二:二进制
方法三:快慢指针
代码:
1 |
160. 实现 Trie (前缀树)-中等
题目:
Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查
请你实现 Trie 类:
Trie()初始化前缀树对象void insert(String word)向前缀树中插入字符串wordboolean search(String word)如果字符串word在前缀树中,返回true(即,在检索之前已经插入);否则,返回falseboolean startsWith(String prefix)如果之前已经插入的字符串word的前缀之一为prefix,返回true;否则,返回false
思路:
字典树
代码:
1 |
161. 数据流的中位数-困难
题目:
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
- void addNum(int num) - 从数据流中添加一个整数到数据结构中
- double findMedian() - 返回目前所有元素的中位数
思路:
方法一:优先队列
方法二:有序集合 + 双指针
代码:
1 |
162. 二叉树展开为链表-中等
题目:
给你二叉树的根结点 root ,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null - 展开后的单链表应该与二叉树 先序遍历 顺序相同
思路:
方法一:前序遍历
方法二:前序遍历和展开同步进行
方法三:寻找前驱节点
代码:
1 |
163. 接近的三数之和-中等
题目:
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近
返回这三个数的和
假定每组输入只存在恰好一个解
思路:
排序 + 双指针
代码:
1 |
164. 打家劫舍 II-中等
题目:
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额
思路:
动态规划
代码:
1 |
165. 三角形最小路径和-中等
题目:
给定一个三角形 triangle ,找出自顶向下的最小路径和
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1
思路:
方法一:动态规划
方法二:动态规划 + 空间优化
代码:
1 |
166. 顺时针打印矩阵-简单
题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字
思路:
方法一:模拟
方法二:按层模拟
代码:
1 |
167. 正则表达式匹配-困难
题目:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配
'.'匹配任意单个字符'*'匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串
思路:
动态规划
代码:
1 |
168. 从中序与后序遍历序列构造二叉树-中等
题目:
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗二叉树
思路:
方法一:递归
方法二:迭代
代码:
1 |
169. 第 N 位数字-中等
题目:
给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字
思路:
方法一:二分查找
方法二:直接计算
代码:
1 |
170. 树的子结构-中等
题目:

思路:
代码:
1 |
171. 链表求和-中等
题目:
给定两个用链表表示的整数,每个节点包含一个数位
这些数位是反向存放的,也就是个位排在链表首部
编写函数对这两个整数求和,并用链表形式返回结果
思路:
模拟
代码:
1 |
172. 有效的括号字符串-中等
题目:
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
- 任何左括号
(必须有相应的右括号) - 任何右括号
)必须有相应的左括号( - 左括号
(必须在对应的右括号之前) *可以被视为单个右括号),或单个左括号(,或一个空字符串- 一个空字符串也被视为有效字符串
思路:
方法一:动态规划
方法二:栈
方法三:贪心
代码:
1 |
173. 两个链表的第一个公共节点-简单
题目:

思路:
方法一:哈希集合
方法二:双指针
代码:
1 |
174. 前 K 个高频元素-中等
题目:
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案
思路:
方法一:堆
方法二:基于快速排序
代码:
1 |
175. 不同的二叉搜索树-中等
题目:
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数
思路:
方法一:动态规划
方法二:数学
代码:
1 |
176. 两个数组的交集-简单
题目:
给定两个数组 nums1 和 nums2 ,返回它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序
思路:
方法一:两个集合
方法二:排序 + 双指针
代码:
1 |
177. 36进制加法-中等
题目:
字节高频题
思路:
代码:
1 |
178. 数组中出现次数超过一半的数字-简单
题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
你可以假设数组是非空的,并且给定的数组总是存在多数元素
思路:
方法一:哈希表
方法二:排序
方法三:随机化
方法四:分治
方法五:Boyer-Moore 投票算法
代码:
1 |
179. Excel表列名称-简单
题目:
给你一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称
例如:
1 | A -> 1 |
思路:
数学
代码:
1 |
180. 扑克牌中的顺子-简单
题目:
从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14
思路:
代码:
1 |
181. 鸡蛋掉落-困难
题目:
给你 k 枚相同的鸡蛋,并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑
已知存在楼层 f ,满足 0 <= f <= n ,任何从 高于 f 的楼层落下的鸡蛋都会碎,从 f 楼层或比它低的楼层落下的鸡蛋都不会破
每次操作,你可以取一枚没有碎的鸡蛋并把它从任一楼层 x 扔下(满足 1 <= x <= n)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用 这枚鸡蛋
请你计算并返回要确定 f 确切的值 的 最小操作次数 是多少?
思路:
方法一:动态规划 + 二分查找
方法二:决策单调性
方法三:数学法
代码:
1 |
182. 最长递增子序列的个数-中等
题目:
给定一个未排序的整数数组 nums , 返回最长递增子序列的个数
注意 这个数列必须是 严格 递增的
思路:
方法一:动态规划
方法二:贪心 + 前缀和 + 二分查找
代码:
1 |
183. 简化路径-中等
题目:
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠
'/'开头 - 两个目录名之间必须只有一个斜杠
'/' - 最后一个目录名(如果存在)不能 以
'/'结尾 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'或'..')
返回简化后得到的 规范路径
思路:
栈
代码:
1 |
184. 数组中重复的数据-中等
题目:
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题
思路:
方法一:将元素交换到对应的位置
方法二:使用正负号作为标记
代码:
1 |
185. 斐波那契数-简单
题目:
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
1 | F(0) = 0,F(1) = 1 |
给定 n ,请计算 F(n)
思路:
方法一:动态规划
方法二:矩阵快速幂
方法三:通项公式
代码:
1 |
186. 删除字符串中的所有相邻重复项-简单
题目:
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们
在 S 上反复执行重复项删除操作,直到无法继续删除
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一
思路:
栈
代码:
1 |
187. 加油站-中等
题目:
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空
给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的
思路:
一次遍历
代码:
1 |
188. 有效三角形的个数-中等
题目:
给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数
思路:
方法一:排序 + 二分查找
方法二:排序 + 双指针
代码:
1 |
189. 最大连续1的个数 III-中等
题目:
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回数组中连续 1 的最大个数
思路:
方法一:二分查找
方法二:滑动窗口
代码:
1 |
190. 二叉树中和为某一值的路径-中等
题目:
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径
叶子节点 是指没有子节点的节点
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
191. 在排序数组中查找数字 I-简单
题目:
统计一个数字在排序数组中出现的次数
思路:
二分查找
代码:
1 |
192. 分隔链表-中等
题目:
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前
你应当 保留 两个分区中每个节点的初始相对位置
思路:
模拟
代码:
1 |
193. 24 点游戏-困难
题目:
给定一个长度为4的整数数组 cards 。你有 4 张卡片,每张卡片上都包含一个范围在 [1,9] 的数字。您应该使用运算符 ['+', '-', '*', '/'] 和括号 '(' 和 ')' 将这些卡片上的数字排列成数学表达式,以获得值24
你须遵守以下规则:
- 除法运算符
'/'表示实数除法,而不是整数除法- 例如,
4 /(1 - 2 / 3)= 4 /(1 / 3)= 12
- 例如,
- 每个运算都在两个数字之间。特别是,不能使用
“-”作为一元运算符- 例如,如果
cards =[1,1,1,1],则表达式“-1 -1 -1 -1”是 不允许 的
- 例如,如果
- 你不能把数字串在一起
- 例如,如果
cards =[1,2,1,2],则表达式“12 + 12”无效
- 例如,如果
如果可以得到这样的表达式,其计算结果为 24 ,则返回 true ,否则返回 false
思路:
回溯
代码:
1 |
194. 二叉树的最小深度-简单
题目:
给定一个二叉树,找出其最小深度
最小深度是从根节点到最近叶子节点的最短路径上的节点数量
说明:叶子节点是指没有子节点的节点
思路:
方法一:深度优先搜索
方法二:广度优先搜索
代码:
1 |
195. 下一个更大元素 III-中等
题目:
给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1
注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1
思路:
方法一:下一个排列
方法二:数学
代码:
1 |
196. 通配符匹配-困难
题目:
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配
1 | '?' 可以匹配任何单个字符。 |
两个字符串完全匹配才算匹配成功
说明:
s可能为空,且只包含从a-z的小写字母p可能为空,且只包含从a-z的小写字母,以及字符?和*
思路:
方法一:动态规划
方法二:贪心算法
代码:
1 |
197. 完全平方数-中等
题目:
给你一个整数 n ,返回和为 n 的完全平方数的最少数量
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是
思路:
方法一:动态规划
方法二:数学
代码:
1 |
198. 解数独-困难
题目:
编写一个程序,通过填充空格来解决数独问题
数独的解法需 遵循如下规则:
- 数字
1-9在每一行只能出现一次 - 数字
1-9在每一列只能出现一次 - 数字
1-9在每一个以粗实线分隔的3x3宫内只能出现一次
数独部分空格内已填入了数字,空白格用 '.' 表示
思路:
方法一:回溯
方法二:位运算优化
方法三:枚举优化
代码:
1 |
199. 阿拉伯数字转中文数字-中等
题目:
思路:
代码:
200. 反转字符串-简单
题目:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题
思路:
双指针
代码:
1 |
本文链接:
https://huajun-chen.github.io/2022/11/14/CodeTop算法题/