学习目标:
目标:熟练运用Java所学知识
学习内容:
本文内容:使用java解决
题目描述
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
解题思路
使用归并排序
- 使用快慢指针法找到链表的中间结点
- 将链表以中间结点为界限拆分链表,得到两个新链表
- 递归的将两个新链表使用以上步骤拆分,直到链表只剩一个节点
- 再对两个链表进行排序,合并得到一个新的链表
- 递归的对两个链表进行排序,最终得到排序后的链表
实现代码
public class LeetCode_148 {
public ListNode sortList(ListNode head) {
return sortList(head,null);
}
public ListNode sortList(ListNode head,ListNode tail){
if(head==null){
return head;
}
if(head.next==tail){
//1.当tail为空时,链表只有head一个节点,则返回head
//2.tail不为空,链表只有两个节点,则从中间断开,
// 因为归并排序使用的是前闭后开区间
head.next=null;
return head;
}
//通过快慢指针法找到链表中间结点
ListNode slow=head,fast=head;
while(fast!=tail&&fast.next!=tail){
slow=slow.next;
fast=fast.next.next;
}
ListNode mid=slow;
//拆
ListNode list1=sortList(head,mid);//递归的减小链表长度
ListNode list2=sortList(mid,tail);//递归的减小链表长度
//合
return merge(list1,list2);
}
//合并两个排序链表
public static ListNode merge(ListNode list1,ListNode list2){
ListNode cur1=list1;
ListNode cur2=list2;
ListNode newhead=new ListNode(0);//合并后的新链表
ListNode newtail=newhead;
while(cur1!=null&&cur2!=null){
if(cur1.val<=cur2.val){
//cur1结点的值小于等于cur2结点的值
newtail.next=cur1;
cur1=cur1.next;
}else{
//cur1结点的值大于cur2结点的值
newtail.next=cur2;
cur2=cur2.next;
}
newtail=newtail.next;
}
if(cur1!=null){
newtail.next=cur1;
}else{
newtail.next=cur2;
}
return newhead.next;
}
}