前言
本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构请见LeetCode 刷题汇总
正文
幕布
21. 合并两个有序链表
题解
Java, 1 ms, 4 lines codes, using recursion
temp.next=递归
object Solution {
def mergeTwoLists(l1: ListNode, l2: ListNode): ListNode = {
if (l1 == null || l2 == null) {
return if (l1 == null) l2 else l1
}
val temp = if (l1.x < l2.x) l1 else l2
temp.next = mergeTwoLists(temp.next, if (temp == l1) l2 else l1)
temp
}
}
22. 括号生成
题解
Easy to understand Java backtracking solution
left ,right , char[],left < sum,left > right
class Solution {
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
helper(res, new char[2 * n], 0, n, 0, 0);
return res;
}
private void helper(List<String> list, char[] chars, int index, int sum, int left, int right){
if(index == 2 * sum){
list.add(new String(chars));
return;
}
if(left < sum){
chars[index] = '(';
helper(list, chars, index + 1, sum, left + 1, right);
}
if(left > right){
chars[index] = ')';
helper(list, chars, index + 1, sum, left, right + 1);
}
}
}
23. 合并K个升序链表
优先列表,哨兵
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
// 优先队列
PriorityQueue<ListNode> queue= new PriorityQueue<>(lists.length, (o1, o2) -> {
if (o1.val < o2.val) return -1;
else if (o1.val == o2.val) return 0;
else return 1;
});
// 单链表中常见的哨兵
ListNode dummy = new ListNode(0), cur = dummy;
for (ListNode node : lists)
if (node != null) queue.add(node);
while (!queue.isEmpty()){
cur.next = queue.poll();
cur = cur.next;
if (cur.next != null) queue.add(cur.next);
}
return dummy.next;
}
}
题解
A java solution based on Priority Queue
两两合并
object Solution {
def mergeKLists(lists: Array[ListNode]): ListNode = {
if(lists.isEmpty) return null
var len = lists.length
while(len != 1){
// 两两合并
for(i <- 0 until len / 2) lists(i) = mergeTwo(lists(i * 2), lists(i * 2 + 1))
// 链表数组长度为奇数,会多出一个链表
if(len % 2 == 1) lists(len / 2) = lists(len - 1)
// 每次长度减半
len = (len + 1) / 2
}
lists(0)
}
/**
* 合并两个单链表
* @param node1 链表 1
* @param node2 链表 2
* @return 返回合并后的链表
*/
private def mergeTwo(node1: ListNode, node2: ListNode): ListNode = {
if(node1 == null) return node2;
if(node2 == null) return node1;
val dummy = new ListNode(0)
var cur = dummy
var cur1 = node1
var cur2 = node2
while(cur1 != null || cur2 != null){
if(cur2 == null || cur1 != null && cur1.x < cur2.x){
cur.next = cur1
cur1 = cur1.next
}else{
cur.next = cur2
cur2 = cur2.next
}
cur = cur.next
}
dummy.next
}
}
题解
My simple java Solution use recursion
24. 两两交换链表中的节点
head.next=递归,next.next=head
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode next = head.next;
head.next = swapPairs(next.next);
next.next = head;
return next;
}
}
题解
My accepted java code. used recursion.
迭代,next,next.next
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode temp = dummy;
while (temp.next != null && temp.next.next != null) {
ListNode node1 = temp.next;
ListNode node2 = temp.next.next;
temp.next = node2;
node1.next = node2.next;
node2.next = node1;
temp = node1;
}
return dummy.next;
}
}
题解
My simple JAVA solution for share
25. K 个一组翻转链表
题解
找到反转点,反转前面的,递归后面的
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
// nextHead指向链表中除去k个节点之后的头节点
// 初始指向节点head
ListNode nextHead = head;
// 链表中剩余节点个数
int remainNum = 0;
while (remainNum < k){
// 根据题意如果链表剩余节点个数不足k个
// 则不需要反转,因此直接返回head
if (nextHead == null) {
return head;
}
remainNum++;
nextHead = nextHead.next;
}
// 递归反转链表中除去前k个节点的后续节点
ListNode subList = reverseKGroup(nextHead,k);
// 反转链表中前k个节点
ListNode newHead = reverseTopN(head, k);
// 前k个节点反转后,head指向的节点是反转后的链表中的最后一个节点
// 因此head指向的节点的后继指针指向subList
head.next = subList;
return newHead;
}
private ListNode reverseTopN(ListNode head, int n) {
ListNode prev = null;
// 当前考察的节点
ListNode cur = head;
// num小于n,则表示当前节点需要反转
for(int num = 0; num < n; num++){
// 当前节点的下一个节点
ListNode next = cur.next;
// 当前节点的后继指针指向prev
cur.next = prev;
// prev指向当前节点
// 表示其是next节点反转后的前一个节点
prev = cur;
// cur指向下一个节点
// 表示下一个节点是待反转节点
cur = next;
}
return prev;
}
}