题目来源:合并两个有序链表

两个链表有序,这个很类似于归并排序的归并过程,但是数组的归并过程会创建一个临时数组,这里如果创建一个临时链表开销就比较大了,因此需要考虑原地排序算法
非递归方案
首先我们定义一个ans节点,用来保存排序后的头节点
然后定义一个prev节点,表示经过排序后的当前节点
首先比较list1和list2的val大小,让prev.next指向较小的那个,然后让较小的那个后移
然后prev = prev.next,继续执行比较的操作
直到list1或者list2为空,最后记得让prev.next指向不为空的那个节点
最后返回的时候,返回ans.next即可
/**
* 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 list1, ListNode list2) {
ListNode ans = new ListNode();
ListNode prev = ans;
while(list1 != null && list2 != null){
if(list1.val < list2.val){
prev.next = list1; //将前面排序好的节点的next指向list
list1 = list1.next; //让小的那个指针后移
prev = prev.next; //更新prev,使其指向最近更新的那个节点
}else{
prev.next = list2;
list2 = list2.next;
prev = prev.next;
}
}
if(list1 != null)prev.next = list1; //最后记得把没走完的那个链表接上
if(list2 != null)prev.next = list2;
return ans.next;
}
}
递归方案
使用递归解决的思路就是:
既然这个函数返回的是排序好的链表的头节点,那么
- 如果
list1.val < list2.val,那么list1.next = mergeTwoLists(list1.next,list2) - 如果
list2.val < list1.val,那么list2.next = mergeTwoLists(list1,list2.next)
最后递归终止的条件
- 如果
list1 == null,那么就返回list2 - 如果
list2 == null,那么就返回list1
/**
* 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 list1, ListNode list2) {
if(list1 == null)return list2;
if(list2 == null)return list1;
if(list1.val < list2.val){
list1.next = mergeTwoLists(list1.next,list2);
return list1;
}else{
list2.next = mergeTwoLists(list1,list2.next);
return list2;
}
}
}
浙公网安备 33010602011771号