Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

这道混合插入有序链表和我之前那篇混合插入有序数组非常的相似 Merge Sorted Array,仅仅是数据结构由数组换成了链表而已,代码写起来反而更简洁。具体思想就是新建一个链表,然后比较两个链表中的元素值,把较小的那个链到新链表中,由于两个输入链表的长度可能不同,所以最终会有一个链表先完成插入所有元素,则直接另一个未完成的链表直接链入新链表的末尾。代码如下:

C++ 解法一:

class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy = new ListNode(-), *cur = dummy;
while (l1 && l2) {
if (l1->val < l2->val) {
cur->next = l1;
l1 = l1->next;
} else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = l1 ? l1 : l2;
return dummy->next;
}
};

Java 解法一:

public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1), cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
}

下面我们来看递归的写法,当某个链表为空了,就返回另一个。然后核心还是比较当前两个节点值大小,如果 l1 的小,那么对于 l1 的下一个节点和 l2 调用递归函数,将返回值赋值给 l1.next,然后返回 l1;否则就对于 l2 的下一个节点和 l1 调用递归函数,将返回值赋值给 l2.next,然后返回 l2,参见代码如下:

C++ 解法二:

class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};

Java 解法二:

public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}

下面这种递归的写法去掉了 if 从句,看起来更加简洁一些,但是思路并没有什么不同:

C++ 解法三:

class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
ListNode *head = l1->val < l2->val ? l1 : l2;
ListNode *nonhead = l1->val < l2->val ? l2 : l1;
head->next = mergeTwoLists(head->next, nonhead);
return head;
}
};

Java 解法三:

public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode head = (l1.val < l2.val) ? l1 : l2;
ListNode nonhead = (l1.val < l2.val) ? l2 : l1;
head.next = mergeTwoLists(head.next, nonhead);
return head;
}
}

我们还可以三行搞定,简直丧心病狂有木有!

C++ 解法四:

class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1 || (l2 && l1->val > l2->val)) swap(l1, l2);
if (l1) l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
};

Java 解法四:

public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null || (l2 != null && l1.val > l2.val)) {
ListNode t = l1; l1 = l2; l2 = t;
}
if (l1 != null) l1.next = mergeTwoLists(l1.next, l2);
return l1;
}
}

Github 同步地址:

https://github.com/grandyang/leetcode/issues/21

类似题目:

Merge Sorted Array

Merge k Sorted Lists

Sort List

Shortest Word Distance II

参考资料:

https://leetcode.com/problems/merge-two-sorted-lists/

https://leetcode.com/problems/merge-two-sorted-lists/discuss/9714/14-line-clean-C%2B%2B-Solution

https://leetcode.com/problems/merge-two-sorted-lists/discuss/9814/3-lines-C%2B%2B-(12ms)-and-C-(4ms)

https://leetcode.com/problems/merge-two-sorted-lists/discuss/9715/Java-1-ms-4-lines-codes-using-recursion

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 21. Merge Two Sorted Lists 混合插入有序链表的更多相关文章

  1. [LeetCode] Merge Two Sorted Lists 混合插入有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  2. [LintCode] Merge Two Sorted Lists 混合插入有序链表

    Merge two sorted (ascending) linked lists and return it as a new sorted list. The new sorted list sh ...

  3. [leetcode]21. Merge Two Sorted Lists合并两个链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  4. 21. Merge Two Sorted Lists (Java 合并有序链表 空间复杂度O(1))

    题目: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ...

  5. [LeetCode] 21. Merge Two Sorted Lists 合并有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  6. [leetcode] 21. Merge Two Sorted Lists (Easy)

    合并链表 Runtime: 4 ms, faster than 100.00% of C++ online submissions for Merge Two Sorted Lists. class ...

  7. LeetCode 21. Merge Two Sorted Lists (合并两个有序链表)

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  8. LeetCode 21 -- Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  9. Java [leetcode 21]Merge Two Sorted Lists

    题目描述: Merge two sorted linked lists and return it as a new list. The new list should be made by spli ...

随机推荐

  1. [NewLife.XCode]实体工厂(拦截处理实体操作)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  2. Azure EA (1) 查看国内Azure账单

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China 有关Azure EA Portal的详细内容,可以参考我的GitHu ...

  3. python-6-for循环及format三种用法

    前言 循环我们前面讲过了无限循环,那么for循环属于什么循环呢?显然就是有限循环: 另外格式化输出我们前面也讲过,但是format也能做到不一样的格式化输出.一起看看吧! 一.for 循环 1.fro ...

  4. LeetCode 133:克隆图 Clone Graph

    题目: 给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]). Given a reference of a ...

  5. 应用层内存溢出/越界/重复释放等问题检查工具(ASan)

    https://github.com/google/sanitizers/wiki https://github.com/google/sanitizers/wiki/AddressSanitizer ...

  6. spring的@ControllerAdvice注解

    @ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理. 对于@ControllerAdvic ...

  7. Neo4j 第十一篇:Cypher函数

    Cypher函数是对图进行查询和操作的重要工具. 一,谓词函数 谓词函数返回true或者false,主要用于检查是否存在或满足特定的条件. 1,Exists 如果指定的模式存在于图中,或者特定的属性存 ...

  8. DesignPattern系列__07合成复用原则

    基本介绍 合成复用原则的核心,就是尽量去使用组合.聚合等方式,而不是使用继承. 核心思想 1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起. 2.针对接口编程,而不是 ...

  9. 命令 docker rm | docker rmi | docker prune 的差异

    区别: docker rm : 删除一个或多个 容器 docker rmi : 删除一个或多个 镜像 docker prune : 用来删除不再使用的 docker 对象 一.docker rm 命令 ...

  10. SqlServer数据库之游标

    游标的简单实现,直接上SQL语句 --循环对每一个代理统计业绩 DECLARE cursor_name CURSOR FOR --定义游标 需要进行游标的数据表 SELECT * FROM #Agen ...