题目:合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
这里要注意的是,题目要求使用单向链表来实现。如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
}
}
思路:其实这题就是要两个链表各取一个元素进行比较,谁小就拿走谁的node,放到最终结果链表中。被拿走的链表,指针后移一位,也就是指向当前的node的next node。
所以我们实现一个简洁版本的示例,具体逻辑都在代码的注释里:
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//这两个if进行空判断,如果l1为空返回l2,
// 即使l2为空也没关系,两个都为空,
// 本来也要返回空
if(l1 == null) {
return l2;
}
if(l2 == null) {
return l1;
}
//创建一个返回ListNode
ListNode result = new ListNode();
//将返回的ListNode付给一个新的ListNode,
// 作用是在后续操作,都操作ListNode,
// result最后返回合并后的链表的起始地址
ListNode resultCurr = result;
//while就是循环比较两个链表的大小,放入resultCurr中
while(l1 != null && l2 != null) {
if(l1.val > l2.val) {
resultCurr.next = l2;
//被取走一个值的链表,指针需要往后挪一个
l2 = l2.next;
} else {
resultCurr.next = l1;
//被取走一个值的链表,指针需要往后挪一个
l1 = l1.next;
}
resultCurr = resultCurr.next;
}
//这里处理的场景是l1和l2长度不一致的时候,
// 其中一个链表短,while判断后结束了循环,
// 另一个链表的剩下的元素,需要追加到resultCurr中
resultCurr.next = l1 == null ? l2 : l1;
//这里返回的是result.next,而不是result,
// 是因为循环中上来赋值就是从result的next开始的,
// 所以result第一个元素是空的,
// 当然要从第二个元素开始返回
return result.next;
}
如果不明白上面return result.next的逻辑,可以将上面的代码做一下逻辑转换,也就是我对第一个元素正常赋值,最后返回的是也return result。
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode result = new ListNode();
if(l1 == null && l2 == null) {
return null;
}
ListNode currL1 = l1;
ListNode currL2 = l2;
if(currL1 == null) {
result = currL2;
return result;
}
if(currL2 == null) {
result = currL1;
return result;
}
if(l1.val > l2.val) {
ListNode v = new ListNode(l2.val);
result = v;
currL2 = l2.next;
} else {
ListNode v = new ListNode(l1.val);
result = v;
currL1 = l1.next;
}
ListNode resultCurr = result;
while(currL1 != null || currL2 != null) {
if(currL1 == null) {
resultCurr.next = currL2;
break;
}
if(currL2 == null) {
resultCurr.next = currL1;
break;
}
if(currL1.val > currL2.val) {
resultCurr.next = currL2;
currL2 = currL2.next;
} else {
resultCurr.next = currL1;
currL1 = currL1.next;
}
resultCurr = resultCurr.next;
}
return result;
}
这个逻辑要注意循环的控制:while(currL1 != null || currL2 != null),这里是如果其中一个为空了,也继续执行循环,在循环中将另一个链表剩余元素放到结果链表中。