题目:
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
示例:
输入:head = [4,2,1,3] 输出:[1,2,3,4]
思路:
我的想法很简单,先将链表转成数组排序完再转成链表,可以实现但是效率低下
看了题解,其实也可以想到,采用递归归并的方法是比较好的,再写一遍
复杂度:
时间复杂度:归并O(nlogn)
空间复杂度:递归O(n)
代码:
public ListNode sortList(ListNode head) {
if(head == null || head.next == null) return head;
//先将链表转成Arraylist排序
List<Integer> list = new ArrayList<>();
while(head!=null){
list.add(head.val);
head = head.next;
}
Collections.sort(list);
//再转成链表
ListNode res = new ListNode(list.get(0));
ListNode node = res;
for(int i=1;i<list.size();++i){
ListNode temp = new ListNode(list.get(i));
node.next = temp;
node = node.next;
}
return res;
}
法2:
public ListNode sortList(ListNode head) {
//对于排序我们想到二分法和归并都很自然,
//关键是怎么在链表里用
if(head == null || head.next == null) return head;
ListNode fast = head.next,slow = head;
//使用快慢指针来找到链表中点,并断开链表
while(fast!=null && fast.next!=null){
slow=slow.next;
fast=fast.next.next;
}
ListNode tmp = slow.next;
slow.next = null;
//对切割过后的两部分进行递归
ListNode left = sortList(head);
ListNode right = sortList(tmp);
//新建一个链表存结果
ListNode node = new ListNode(0);
ListNode res = node;
while(left!=null && right!=null){
if(left.val<right.val){
node.next=left;
left = left.next;
}else{
node.next=right;
right = right.next;
}
node = node.next;
}
node.next =left!=null?left:right;
return res.next;
}