leetcode 刷题 CS-Notes
文章目录
前言
本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。
数据结构相关
链表
-
归并两个有序的链表
21. Merge Two Sorted Lists (Easy) -
从有序链表中删除重复节点
83. Remove Duplicates from Sorted List (Easy) -
删除链表的倒数第 n 个节点
19. Remove Nth Node From End of List (Medium) -
交换链表中的相邻结点
24. Swap Nodes in Pairs (Medium) -
链表元素按奇偶聚集
328. Odd Even Linked List (Medium)
树
递归
-
两节点的最长路径
543. Diameter of Binary Tree (Easy) -
判断路径和是否等于一个数
112. Path Sum (Easy) -
统计路径和等于一个数的路径数量
437. Path Sum III (Easy) -
统计左叶子节点的和
404. Sum of Left Leaves (Easy) -
相同节点值的最大路径长度
687. Longest Univalue Path (Easy) -
找出二叉树中第二小的节点
671. Second Minimum Node In a Binary Tree (Easy)
层次遍历
-
一棵树每层节点的平均数
637. Average of Levels in Binary Tree (Easy)
前中后序遍历
-
非递归实现二叉树的前序遍历
144. Binary Tree Preorder Traversal (Medium) -
非递归实现二叉树的后序遍历
145. Binary Tree Postorder Traversal (Medium) -
非递归实现二叉树的中序遍历
94. Binary Tree Inorder Traversal (Medium)
BST
-
寻找二叉查找树的第 k 个元素
230. Kth Smallest Element in a BST (Medium) -
把二叉查找树每个节点的值都加上比它大的节点的值
538. Convert BST to Greater Tree (Easy) -
二叉查找树的最近公共祖先
235. Lowest Common Ancestor of a Binary Search Tree (Easy) -
二叉树的最近公共祖先
236. Lowest Common Ancestor of a Binary Tree (Medium) -
从有序数组中构造二叉查找树
108. Convert Sorted Array to Binary Search Tree (Easy) -
根据有序链表构造平衡的二叉查找树
109. Convert Sorted List to Binary Search Tree (Medium) -
在二叉查找树中寻找两个节点,使它们的和为一个给定值
653. Two Sum IV - Input is a BST (Easy) -
在二叉查找树中查找两个节点之差的最小绝对值
530. Minimum Absolute Difference in BST (Easy) -
寻找二叉查找树中出现次数最多的值
501. Find Mode in Binary Search Tree (Easy)
Trie
-
实现一个 Trie,用来求前缀和
677. Map Sum Pairs (Medium)
栈和队列
-
用栈实现括号匹配
20. Valid Parentheses (Easy) -
数组中元素与下一个比它大的元素之间的距离
739. Daily Temperatures (Medium) -
循环数组中比当前元素大的下一个元素
503. Next Greater Element II (Medium)
哈希表
-
数组中两个数的和为给定值
1. Two Sum (Easy) -
判断数组是否含有重复元素
217. Contains Duplicate (Easy)
字符串
-
字符串循环移位包含
给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。
s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。
-
字符串循环移位
将字符串向右循环移动 k 位。
将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba321,然后对整个字符串进行翻转,得到 123abcd。
-
字符串中单词的翻转
将每个单词翻转,然后将整个字符串翻转。
-
两个字符串包含的字符是否完全相同
242. Valid Anagram (Easy) -
计算一组字符集合可以组成的回文字符串的最大长度
409. Longest Palindrome (Easy) -
回文子字符串个数
647. Palindromic Substrings (Medium) -
判断一个整数是否是回文数
9. Palindrome Number (Easy) -
统计二进制字符串中连续 1 和连续 0 数量相同的子字符串个数
696. Count Binary Substrings (Easy)
数组与矩阵
-
把数组中的 0 移到末尾
283. Move Zeroes (Easy) -
找出数组中最长的连续 1
485. Max Consecutive Ones (Easy) -
有序矩阵的 Kth Element
378. Kth Smallest Element in a Sorted Matrix ((Medium)) -
一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
645. Set Mismatch (Easy) -
找出数组中重复的数,数组值在 [1, n] 之间
287. Find the Duplicate Number (Medium) -
数组相邻差值的个数
667. Beautiful Arrangement II (Medium) -
对角元素相等的矩阵
766. Toeplitz Matrix (Easy)
图
二分图
- 判断是否为二分图
785. Is Graph Bipartite? (Medium)
拓扑排序
-
课程安排的合法性
207. Course Schedule (Medium) -
课程安排的顺序
210. Course Schedule II (Medium)
并查集
位运算
-
统计两个数的二进制表示有多少位不同
461.Hamming Distance (Easy) -
数组中唯一一个不重复的元素
136. Single Number (Easy) -
找出数组中缺失的那个数
268. Missing Number (Easy) -
数组中不重复的两个元素
260. Single Number III (Medium) -
翻转一个数的比特位
190. Reverse Bits (Easy) -
不用额外变量交换两个整数 程序员代码面试指南 :P317
-
判断一个数是不是 2 的 n 次方
231. Power of Two (Easy) -
判断一个数是不是 4 的 n 次方
342. Power of Four (Easy) -
判断一个数的位级表示是否不会出现连续的 0 和 1
693. Binary Number with Alternating Bits (Easy) -
求一个数的补码
476. Number Complement (Easy) -
实现整数的加法
371. Sum of Two Integers (Easy) -
统计从 0 ~ n 每个数的二进制表示中 1 的个数
338. Counting Bits (Medium)
算法思想
双指针
-
有序数组的 Two Sum
167. Two Sum II - Input array is sorted (Easy) -
反转字符串中的元音字符
345. Reverse Vowels of a String (Easy) -
归并两个有序数组
88. Merge Sorted Array (Easy) -
判断链表是否存在环
141. Linked List Cycle (Easy) -
最长子序列
524. Longest Word in Dictionary through Deleting (Medium)
排序
快速选择
用于求解 Kth Element 问题,也就是第 K 个元素的问题。可以使用快速排序的 partition()
进行实现。需要先打乱数组,否则最坏情况下时间复杂度为$ O(N^2) $。
堆
用于求解 TopK Elements 问题,也就是 K 个最小元素的问题。使用最小堆来实现 TopK 问题,最小堆使用大顶堆来实现,大顶堆的堆顶元素为当前堆的最大元素。实现过程:不断地往大顶堆中插入新元素,当堆中元素的数量大于 k 时,移除堆顶元素,也就是当前堆中最大的元素,剩下的元素都为当前添加过的元素中最小的 K 个元素。插入和移除堆顶元素的时间复杂度都为 log2N。
堆也可以用于求解 Kth Element 问题,得到了大小为 K 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 K 大的元素。
快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。
可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。
- Kth Element
215. Kth Largest Element in an Array (Medium)
桶排序
-
出现频率最多的 k 个元素
347. Top K Frequent Elements (Medium) -
按照字符出现次数对字符串排序
451. Sort Characters By Frequency (Medium)
荷兰国旗问题
荷兰国旗包含三种颜色:红、白、蓝。
有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。
- 按颜色进行排序
75. Sort Colors (Medium)
贪心思想
-
投飞镖刺破气球
452. Minimum Number of Arrows to Burst Balloons (Medium) -
根据身高和序号重组队列
406. Queue Reconstruction by Height(Medium) -
买卖股票的最大收益 II
122. Best Time to Buy and Sell Stock II (Easy) -
判断是否为子序列
392. Is Subsequence (Medium) -
修改一个数成为非递减数组
665. Non-decreasing Array (Easy) -
子数组最大的和
53. Maximum Subarray (Easy) -
分隔字符串使同种字符出现在一起
763. Partition Labels (Medium)
二分查找
-
大于给定元素的最小元素
744. Find Smallest Letter Greater Than Target (Easy) -
有序数组的 Single Element
540. Single Element in a Sorted Array (Medium) -
第一个错误的版本
278. First Bad Version (Easy) -
旋转数组的最小数字
153. Find Minimum in Rotated Sorted Array (Medium) -
查找区间
34. Find First and Last Position of Element in Sorted Array
分治
搜索
BFS
-
计算在网格中从原点到特定点的最短路径长度
1091. Shortest Path in Binary Matrix(Medium) -
组成整数的最小平方数数量
279. Perfect Squares (Medium) -
最短单词路径
127. Word Ladder (Medium)
DFS
-
查找最大的连通面积
695. Max Area of Island (Medium) -
矩阵中的连通分量数目
200. Number of Islands (Medium) -
好友关系的连通分量数目
547. Friend Circles (Medium) -
能到达的太平洋和大西洋的区域
417. Pacific Atlantic Water Flow (Medium)
Backtracking
-
IP 地址划分
93. Restore IP Addresses(Medium) -
在矩阵中寻找字符串
79. Word Search (Medium) -
输出二叉树中所有从根到叶子的路径
257. Binary Tree Paths (Easy) -
含有相同元素求排列
47. Permutations II (Medium) -
含有相同元素的组合求和
40. Combination Sum II (Medium) -
1-9 数字的组合求和
216. Combination Sum III (Medium) -
含有相同元素求子集
90. Subsets II (Medium) -
分割字符串使得每个部分都是回文数
131. Palindrome Partitioning (Medium) -
N 皇后
51. N-Queens (Hard)
动态规划
斐波那契数列
-
强盗在环形街区抢劫
213. House Robber II (Medium) -
信件错排
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式的数量。
定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况:
-
i==k,交换 i 和 j 的信后,它们的信和信封在正确的位置,但是其余 i-2 封信有 dp[i-2] 种错误装信的方式。由于 j 有 i-1 种取值,因此共有 (i-1)*dp[i-2] 种错误装信方式。
-
i != k,交换 i 和 j 的信后,第 i 个信和信封在正确的位置,其余 i-1 封信有 dp[i-1] 种错误装信方式。由于 j 有 i-1 种取值,因此共有 (i-1)*dp[i-1] 种错误装信方式。
综上所述,错误装信数量方式数量为: d p [ i ] = ( i − 1 ) × d p [ i − 2 ] + ( i − 1 ) × d p [ i − 1 ] dp[i]=(i-1) \times dp[i-2] + (i-1) \times dp[i-1] dp[i]=(i−1)×dp[i−2]+(i−1)×dp[i−1]
-
-
母牛生产
程序员代码面试指南-P181
题目描述:假设农场中成熟的母牛每年都会生 1 头小母牛,并且永远不会死。第一年有 1 只小母牛,从第二年开始,母牛开始生小母牛。每只小母牛 3 年之后成熟又可以生小母牛。给定整数 N,求 N 年后牛的数量。第 i 年成熟的牛的数量为: d p [ i ] = d p [ i − 1 ] + d p [ i − 3 ] dp[i] = dp[i-1] + dp[i-3] dp[i]=dp[i−1]+dp[i−3]
矩阵路径
-
矩阵的最小路径和
64. Minimum Path Sum (Medium) -
矩阵的总路径数
62. Unique Paths (Medium)
数组区间
-
数组中等差递增子区间的个数
413. Arithmetic Slices (Medium)
分割整数
-
分割整数的最大乘积
343. Integer Break (Medim) -
按平方数来分割整数
279. Perfect Squares(Medium) -
分割整数构成字母字符串
91. Decode Ways (Medium)
最长递增子序列
-
一组整数对能够构成的最长链
646. Maximum Length of Pair Chain (Medium) -
最长摆动子序列
376. Wiggle Subsequence (Medium)
最长公共子序列
- 最长公共子序列
1143. Longest Common Subsequence
0-1 背包
-
划分数组为和相等的两部分
416. Partition Equal Subset Sum (Medium) -
改变一组数的正负号使得它们的和为一给定数
494. Target Sum (Medium) -
01 字符构成最多的字符串
474. Ones and Zeroes (Medium) -
找零钱的最少硬币数
322. Coin Change (Medium) -
找零钱的硬币数组合
518. Coin Change 2 (Medium) -
字符串按单词列表分割
139. Word Break (Medium)
股票交易
-
需要冷却期的股票交易
309. Best Time to Buy and Sell Stock with Cooldown(Medium) -
需要交易费用的股票交易
714. Best Time to Buy and Sell Stock with Transaction Fee (Medium) -
只能进行两次的股票交易
123. Best Time to Buy and Sell Stock III (Hard) -
只能进行 k 次的股票交易
188. Best Time to Buy and Sell Stock IV (Hard)
字符串编辑
-
删除两个字符串的字符使它们相等
583. Delete Operation for Two Strings (Medium)
数学13
素数分解
整除
最大公约数最小公倍数
令: x = 2 m 0 × 3 m 1 × 5 m 2 × 7 m 3 × . . . . x = 2 ^{m0} \times 3^{m1} \times 5 ^ {m2} \times 7^{m3} \times .... x=2m0×3m1×5m2×7m3×.... y = 2 n 0 × 3 n 1 × 5 n 2 × 7 n 3 × . . . . y = 2 ^{n0} \times 3^{n1} \times 5 ^ {n2} \times 7^{n3} \times .... y=2n0×3n1×5n2×7n3×....
则: g c d ( x , y ) = 2 m i n ( m 0 , n 0 ) × 3 m i n ( m 1 , n 1 ) × 5 m i n ( m 2 , n 2 ) × . . . gcd(x,y) = 2 ^{min(m0,n0)} \times 3 ^ {min(m1, n1)} \times 5 ^ {min(m2, n2)} \times ... gcd(x,y)=2min(m0,n0)×3min(m1,n1)×5min(m2,n2)×... l c d ( x , y ) = 2 m a x ( m 0 , n 0 ) × 3 m a x ( m 1 , n 1 ) × 5 m a x ( m 2 , n 2 ) × . . . lcd(x,y) = 2 ^{max(m0,n0)} \times 3 ^ {max(m1, n1)} \times 5 ^ {max(m2, n2)} \times ... lcd(x,y)=2max(m0,n0)×3max(m1,n1)×5max(m2,n2)×...
-
生成素数序列
204. Count Primes (Easy) -
最大公约数
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
最小公倍数为两数的乘积除以最大公约数。
int lcm(int a, int b) { return a * b / gcd(a, b); }
-
使用位操作和减法求解最大公约数
对于 a 和 b 的最大公约数 f(a, b),有:
- 如果 a 和 b 均为偶数,f(a, b) = 2*f(a/2, b/2);
- 如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b);
- 如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2);
- 如果 a 和 b 均为奇数,f(a, b) = f(b, a-b);
乘 2 和除 2 都可以转换为移位操作。
进制转换
-
7 进制
504. Base 7 (Easy)
阶乘
- 统计阶乘尾部有多少个 0
172. Factorial Trailing Zeroes (Easy)
字符串加法减法
-
二进制加法
67. Add Binary (Easy) -
字符串加法
415. Add Strings (Easy)
相遇问题
- 改变数组元素使所有的数组元素都相等
462. Minimum Moves to Equal Array Elements II (Medium)
多数投票问题
- 数组中出现次数多于 n / 2 的元素
169. Majority Element (Easy)
其它
-
3 的 n 次方
326. Power of Three (Easy) -
找出数组中的乘积最大的三个数
628. Maximum Product of Three Numbers (Easy)