合并两个有序链表
【题目】
给定两个有序单链表的头节点head1和head2,请合并两个有序链表,合并后的链表依然有序,并返回合并后的头节点
例如:
0->2->3->7->null
1->3->5->7->9->null
合并后的链表为:
0->1->3->3->5->7->7->9->null
【思路】
- 如果两个链表中一个为空,直接返回另一个链表的头节点即可
- 然后比较head1和head2的值,小的节点也是合并后链表的最小节点,这个节点就是合并后链表的头节点,记为head。在之后的步骤里,哪个链表的头节点的值更小,另一个链表的所有节点都会插入到这个链表中。
- 这里我们假设head节点所在的链表1,另一个链表为链表2.链表1和链表2都从头节点开始一起遍历,比较每次遍历到的两个节点的值,记为cur1和cur2,然后根据大小关系做出不同的调整,同时使用一个变量pre表上上次比较时较小的节点。
假如:链表1为1->5->6->null,链表2为2->3->7->null
此时cur1=1,cur2=2,pre=1。cur1小于cur2,不做调整,因为此时cur1较小,所以令pre=cur1=1,然后继续遍历链表1的下一个节点,也就是节点5.
cur1=5,cur2=2,pre=1。cur1大于cur2,让pre的next指针指向cur2,cur2的next指针指向cur1,这样,cur2便插入到链表1中。因为此时cur2较小,所以令pre=cur2=2,然后继续遍历链表2的下一个节点,也就是3.这一步完成后,链表1变为1->2->5->6->null,链表2为3->7->null。cur1=5,cur2=3,pre=2。
后面依此类推…
- 如果链表1先走完,此时cur1=null,pre为链表的最后一个节点,那么就把pre的next指针指向链表2当前的节点(即cur2),表示把链表2没遍历到的有序部分直接拼接到最后,调整结束。如果链表2先走完,说明链表2的所有节点都已经插入到链表1中,调整结束。
- 返回合并后的头节点head
【代码】
public ListNode mergeTwoLists(ListNode head1,ListNode head2){
if(head1 == null || head2 == null){
return head1 == null ? head2: head1;
}
ListNode head = head1.value <= head2.value ? head1 : head2;
ListNode cur1 = head == head1 ? head1 : head2;
ListNode cur2 = head == head1 ? head2 : head1;
ListNode pre = null;
ListNode next = null;
while(cur1 != null && cur2 != null){
if(cur1.value <= cur2.value){
pre = cur1;
cur1 = cur1.next;
}else {
next = cur2.next;
pre.next = cur2;
cur2.next = cur1;
pre = cur2;
cur2 = next;
}
}
pre.next = cur1 == null ? cur2 : cur1;
reutrn head;
}