Long Luo's Life Notes

每一天都是奇迹

By Long Luo

我的 Leetcode 的解题:


Chinese Solutions

Leetcode题目难度题解
1. 两数之和Easy2种方法:暴力 和 HashMap
2. 两数相加Medium2种方法:模拟 和 递归
4. 寻找两个正序数组的中位数Hard4种方法:合并数组,暴力法,二分搜索,划分数组
15. 三数之和Medium3种方法:暴力,Hash,双指针
18. 四数之和Medium4种方法:暴力,双指针,DFS,HashMap
22. 括号生成Medium2种方法:暴力法 和 回溯法
28. 实现 strStr()Easy理解KMP算法:从入门到推导
29. 两数相除Medium3种方法:暴力法,二分搜索,递归
42. 接雨水Hard5种解法:木桶原理,按行求,动态规划,双指针,单调栈
43. 字符串相乘Medium另辟蹊径,快速傅里叶变换(FFT)计算大数乘法
70. 爬楼梯Easy面试算法题:爬楼梯,N级楼梯有多少种走法?
148. 排序链表Medium4种方法:暴力,List,自顶向下归并排序,自底向上归并排序
155. 最小栈Easy3种方法:辅助栈,栈,链表
171. Excel 表列序号Easy仿照Excel的列编号,给定一个数字,输出该列编号字符串
209. 长度最小的子数组Medium5种方法:暴力,双指针,前缀和,前缀和 + 二分查找,二分查找
225. 用队列实现栈Easy如何改变队列元素顺序?
230. 二叉搜索树中第K小的元素Medium二叉搜索树中第K小的元素
232. 用栈实现队列Easy顺序翻转,使用两个栈:一个入队,一个出队
268. 丢失的数字Medium4种方法:排序,哈希表,异或,数学公式
299. 猜数字游戏Medium从遍历2次优化到遍历1次
318. 最大单词长度乘积Medium3种方法:从暴力状态压缩到位运算优化
384. 打乱数组Medium2种方法:暴力 和 洗牌算法
390. 消除游戏Medium经典算法:从约瑟夫问题说开去…
396. 旋转函数Medium3种方法:暴力法,动态规划,前缀和 + 滑动窗口
407. 接雨水 IIHard2种方法:优先队列存储每层围栏最低高度,BFS更新每个方块存水高度
超大数字的加减乘除 415. 字符串相加, 445. 两数相加 IIMedium超大数字的四则运算是如何实现的呢?
419. 甲板上的战舰Medium4种方法:一次遍历,DFS,统计战舰起点
423. 从英文中重建数字Medium找规律,依次确定数字的次数,逐步消元法
438. 找到字符串中所有字母异位词Medium滑动窗口:从HashMap,数组,再到统计字母数量之差
458. 可怜的小猪Hard从 经典面试问题 到 信息论
509. 斐波那契数Easy9种求斐波那契数(Fibonacci Numbers)的算法
519. 随机翻转矩阵Medium2种方法:暴力法 和 降维 + 哈希表
525. 连续数组Medium2种方法:暴力,前缀和 + 哈希表
559. N叉树的最大深度Easy3种方法:递归,DFS和BFS
594. 最长和谐子序列Easy4种方法:暴力枚举,排序 + 枚举,哈希表
598. 范围求和 IIEasy求所有操作的交集
686. 重复叠加字符串匹配Medium3种方法:暴力,字符串哈希,KMP
700. 二叉搜索树中的搜索Easy3种方法:递归,迭代,BFS
859. 亲密字符串Easy简单的字符串模拟
912. 排序数组Medium排序算法(Sorting Algorithms)
997. 找到小镇的法官Easy图论,计算各节点的入度和出度
1044. 最长重复子串Hard3种方法:从暴力到二分,二分搜索 + 字符串哈希,后缀数组
1218. 最长定差子序列Medium序列动态规划 + HashMap
1385. 两个数组间的距离值Easy2种方法:模拟 和 二分搜索
1705. 吃苹果的最大数目Medium贪心 + 优先队列:每天找最邻近过期的苹果吃
1816. 截断句子Easy3种方法:正则表达式,模拟和优化
meituan-002. 小美的仓库整理Medium记一道美团面试编程题的解题过程:从暴力到优化
阅读全文 »

By Long Luo

148. 排序链表

暴力 + ArrayList

思路与算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}

ListNode pNode = head;

List<Integer> nodeList = new ArrayList<>();
while (pNode != null) {
nodeList.add(pNode.val);
pNode = pNode.next;
}

Collections.sort(nodeList);

ListNode dummyNode = new ListNode(-1);
pNode = dummyNode;
for (int i = 0; i < nodeList.size(); i++) {
pNode.next = new ListNode(nodeList.get(i));
pNode = pNode.next;
}

return dummyNode.next;
}

123

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}

ListNode pNode = head;

List<ListNode> nodeList = new ArrayList<>();
while (pNode != null) {
nodeList.add(pNode);
pNode = pNode.next;
}

nodeList.sort(Comparator.comparingInt(o -> o.val));

ListNode dummyNode = new ListNode(-1);
ListNode preNode = dummyNode;
for (int i = 0; i < nodeList.size(); i++) {
pNode = nodeList.get(i);
preNode.next = pNode;
pNode.next = null;
preNode = pNode;
}

return dummyNode.next;
}

复杂度分析

  • 时间复杂度:\(O(n \log n + n)\)
  • 空间复杂度:\(O(n)\)

归并排序

1
2
3



复杂度分析

  • 时间复杂度:\(O(n \log n + n)\)
  • 空间复杂度:\(O(n)\)

All suggestions are welcome. If you have any query or suggestion please comment below. Please upvote👍 if you like💗 it. Thank you:-)

Explore More Leetcode Solutions. 😉😃💗

By Long Luo

Leetcode 230. 二叉搜索树中第K小的元素 题解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
230. 二叉搜索树中第K小的元素

给定一个二叉搜索树的根节点root,和一个整数$k$,请你设计一个算法查找其中第$k$个最小元素(从$1$开始计数)。

示例 1:
输入:root = [3,1,4,null,2], k = 1
输出:1

示例 2:
输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3

提示:
树中的节点数为 n 。
1 <= k <= n <= 10^4
0 <= Node.val <= 10^4

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第$k$小的值,你将如何优化算法?

方法一:中序遍历 + 递归

思路与算法:

二叉搜索树具有如下性质:

  • 结点的左子树只包含小于当前结点的数。
  • 结点的右子树只包含大于当前结点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

二叉树的中序遍历即按照访问左子树——根结点——右子树的方式遍历二叉树;在访问其左子树和右子树时,我们也按照同样的方式遍历;直到遍历完整棵树。

因为二叉搜索树和中序遍历的性质,所以二叉搜索树的中序遍历是按照键增加的顺序进行的。于是,我们可以通过中序遍历找到第\(k\)个最小元素。

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public int kthSmallest(TreeNode root, int k) {
List<Integer> nums = new ArrayList<>();
inOrder(root, nums);
return nums.get(k - 1);
}

public void inOrder(TreeNode root, List<Integer> numberList) {
if (root == null) {
return;
}

inOrder(root.left, numberList);
numberList.add(root.val);
inOrder(root.right, numberList);
}

复杂度分析:

  • 时间复杂度:\(O(N)\),其中\(N\)是树的节点数。
  • 空间复杂度:\(O(N)\),需要额外存储每个节点的值。
阅读全文 »

By Long Luo

Leetcode 22. 括号生成 题解。

方法一:暴力法

思路与算法:

直接生成所有 \(2^{2n}\) 个’(‘和’)’字符构成的序列,然后我们检查每一个是否有效即可。

为了生成所有序列,我们可以使用递归。长度为 \(n\) 的序列就是在长度为 \(n-1\) 的序列前加一个’(‘或’)’。

为了检查序列是否有效,我们遍历这个序列,并使用一个变量 \(balance\) 表示左括号的数量减去右括号的数量。如果在遍历过程中 \(balance\) 的值小于零,或者结束时 \(balance\) 的值不为零,那么该序列就是无效的,否则它是有效的。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public List<String> generateParenthesis(int n) {
if (n < 1) {
return new ArrayList<>();
}

List<String> ans = new ArrayList<>();
generateAll(new char[2 * n], 0, ans);
return ans;
}

public void generateAll(char[] current, int pos, List<String> result) {
if (pos == current.length) {
if (valid(current)) {
result.add(new String(current));
}
} else {
current[pos] = '(';
generateAll(current, pos + 1, result);
current[pos] = ')';
generateAll(current, pos + 1, result);
}
}

public boolean valid(char[] current) {
int balance = 0;
for (char c : current) {
if (c == '(') {
++balance;
} else {
--balance;
}
if (balance < 0) {
return false;
}
}
return balance == 0;
}

复杂度分析

  • 时间复杂度:\(O(2^{2n}n)\) ,对于 \(2^{2n}\) 个序列中的每一个,我们用于建立和验证该序列的复杂度为 \(O(n)\)
  • 空间复杂度:\(O(n)\) ,除了答案数组之外,我们所需要的空间取决于递归栈的深度,每一层递归函数需要 \(O(1)\) 的空间,最多递归 \(2n\) 层,因此空间复杂度为 \(O(n)\)
阅读全文 »

By Long Luo

Grep 是什么?

grep, g/re/p , (Global / Regular Expression(RE) search / and Print Out the line) ,全面搜索正则表达式并把行打印出来 ,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。用于过滤/搜索的特定字符。可使用正则表达式能配合多种命令使用,使用上十分灵活。

grep searches each FILE for PATTERNS. PATTERNS is a string that contains one or more patterns separated by newline characters, and grep prints each line that matches a pattern. When using grep in a shell command, PATTERNS should usually be quoted.

A FILE of “-” denotes standard input. If no FILE is specified, recursive searches examine the working directory, while nonrecursive searches read standard input.

Furthermore, the variant programs egrep, fgrep, and rgrep are equivalent to grep -E, grep -F, and grep -r, respectively. These variants are obsolete, but remain available for backward compatibility.

Grep 用法

grep [OPTION…] PATTERNS [FILE…]

grep [OPTION…] -e PATTERNS … [FILE…]

grep [OPTION…] -f PATTERN_FILE … [FILE…]

WILDCARDS

.Match any Character Except New Line
?Match 0 or One characters
*Match 0 or More characters
+Match 1 or More characters

QUANTIFIERS

{n}Matches exactly n times
{n,}Matches n or More
{,m}Matches up to m (maximum)
{n,m}Matches between n and m (Minimum, Maximum)

CHARACTER CLASSES

[A-Za-z] Any lower and upper case letters [0-9] Any Number [0-9A-Za-z] Any lower and upper case letter or digits

POSITIONS

^Beginning of line
$End of line
^$Empty line
\<Start of word
\>End of word
阅读全文 »
0%