本篇记录 LeetCode 算法部分第 21 至 25 题。
Merge Two Sorted Lists
第 21 题 Merge Two Sorted Lists
将两个有序链表合并成一个新的有序链表。
题目不复杂,取两个指针分别往下遍历两个链表的每个节点,逐次指向节点的值,取其较小值,并移动该指针,另一指针不动。继续往下比较,知道其中有一个指针到达末端为止。 循环解法:
// MergeTwoSortedLists.java v1.0
// Definition for singly-linked list.
// public class ListNode {
// int val;
// ListNode next;
// ListNode(int x) { val = x; }
// }
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode res = new ListNode(0);
ListNode temp = res;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
temp.next = l1;
l1 = l1.next;
} else {
temp.next = l2;
l2 = l2.next;
}
temp = temp.next;
}
if (l1 == null) temp.next = l2;
else temp.next = l1;
return res.next;
}
}
递归解法:
// MergeTwoSortedLists.java v1.1
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode res = new ListNode(0);
pickListNode(l1, l2, res);
return res.next;
}
private void pickListNode(ListNode l1, ListNode l2, ListNode res) {
if (l1 == null || l2 == null) {
res.next = l1 == null ? l2 : l1;
} else if (l1.val < l2.val) {
res.next = l1;
l1 = l1.next;
pickListNode(l1, l2, res.next);
} else {
res.next = l2;
l2 = l2.next;
pickListNode(l1, l2, res.next);
}
}
}
Status | Tests | Run Time | Language |
---|---|---|---|
Accepted | 208 / 208 | 1 ms | Java |
Generate Parentheses
第 22 题 Generate Parentheses
给定 n 对括号,编写方法生成所有可能的有效组合形式。 例如,n = 3,所有的组合情况为:[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]
这题很容易想起之前做过的第 20 题 Valid Parentheses,当时利用了栈的 FILO 特性去检验括号组合的有效性。一个很直接的想法就是枚举全部的组合,然后传给 Valid Parentheses 方法去做有效性检验。但是这种方法平方级的时间复杂度太高,因为要判断所有组合。
n + 1 对括号的组合,可以发现,其实就是将新增的一对括号和之前的 n 对括号的组合拼起来。因此这里就可以利用递归的思想。
n 对括号组合,就需要把 n 个 "("
和 n 个 ")"
插入进字符串中。而且从左往右,"("
的数量一定不少于 ")"
才能使得组合有效,换句话说,就是只有在待插入的 ")"
的数量大于待插入的 "("
数量时,才需要往字符串中插入 ")"
。当待插入的括号数量为零时,结束递归,将所得括号字符串添加进列表里。
// GenerateParentheses.java
public class Solution {
public List<String> generateParenthesis(int n) {
List<String> list = new ArrayList<>();
if (n <= 0) return list;
recursive(list, "", n, n);
return list;
}
private void recursive(List<String> result, String paren, int left, int right) {
if (left == 0 && right == 0) {
result.add(paren);
return;
}
if (left > 0) {
recursive(result, paren + "(", left - 1, right);
}
if (right > 0 && left < right) {
recursive(result, paren + ")", left, right - 1);
}
}
}
Status | Tests | Run Time | Language |
---|---|---|---|
Accepted | 8 / 8 | 2 ms | Java |
Merge k Sorted Lists
第 23 题 Merge k Sorted Lists
Swap Nodes in Pairs
第 24 题 Swap Nodes in Pairs
给定一个 Linked list,两两交换相邻节点,返回该链表。 例如,给定的链表为
1 ->2 -> 3 -> 4
,返回结果为2 -> 1 -> 4 -> 3
。
首先需要新建一个 ListNode 保存给定 ListNode 的头指针,这样在交换相邻节点时,该指针位置能保持固定不动。此外还需要另一个 ListNode 作为移动的指针来交换相邻节点,因此还需要创建两个临时的 ListNode,一左一右作交换。
// SwapNodesInPairs.java
public class Solution {
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode swapPairs(ListNode head) {
ListNode res = new ListNode(0);
ListNode curNode = res;
res.next = head;
while (curNode.next != null && curNode.next.next != null) {
ListNode l = curNode.next, r = curNode.next.next;
curNode.next = r;
l.next = r.next;
r.next = l;
curNode = l;
}
return res.next;
}
}
Status | Tests | Run Time | Language |
---|---|---|---|
Accepted | 55 / 55 | 0 ms | Java |
Merge Reverse Nodes in k-Group
第 25 题 Reverse Nodes in k-Group
// MergeReverseNodesInKGroup.java