开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 天,点击查看活动详情
题目三、148. 排序链表
原题链接:148. 排序链表
题目描述:
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
/
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
/
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
/
示例 3:
输入:head = []
输出:[]
/ 提示:
- 链表中节点的数目在范围 [0, 5 * 104] 内
- -105 <= Node.val <= 105
解题思路:
我们需要给链表节点值进行排序。
我是用的排序方法是归并排序,我们知道,归并排序首先需要获得排序元素的中间元素位置。
但是链表又没有办法向数组那样通过下标获取,所以我们需要使用到快慢指针,快指针一次走两个节点,慢指针一次走一个节点,那么快指针遍历到链表结尾时,我们的慢指针所在位置就是中间节点的位置。
这时候我们借助递归,用同样的方式将每一个子链表通过中间节点平分,最后得到单个的节点,然后相邻的两个节点按照升序合并,这就是归并操作。
我们不断对相邻的两个节点进行归并操作,将归并好的节点按照顺序放入准备好的新链表中,最后返回新链表的头节点即可!
最主要还是理解归并排序的步骤、模板。
提交代码:
/**
* 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 sortList(ListNode head) {
return sort(head,null); //调用递归方法
}
//递归方法
public ListNode sort(ListNode head,ListNode tail){
if(head == null){ //头节点为空,返回空值
return head;
}
if(head.next == tail){ //节点最终平分至单节点
head.next = null; //结点指向空值
return head; //返回节点
}
ListNode fast = head,slow = head; //设置快慢指针
while(fast != tail){ //快指针遍历到结尾前
slow = slow.next; //满指针后移
fast = fast.next; //快指针后移
if(fast != tail){ //依旧未到尾部
fast = fast.next; //快指针第二次后移
}
}
ListNode mid = slow; //中间节点就是满指针当前节点
ListNode list1 = sort(head,mid); //同样方式平分左子链表
ListNode list2 = sort(mid,tail); //同样方式平分右子链表
ListNode sorted = merge(list1,list2); //调用归并操作方法
return sorted; //返回升序链表头节点
}
public static ListNode merge(ListNode list1,ListNode list2){
//创建新的链表,存放升序节点
ListNode list = new ListNode();
ListNode temp1 = list1; //两个相邻的链表
ListNode temp2 = list2;
ListNode temp = list;
while(temp1 != null && temp2 != null){ //对相邻链表进行归并操作
if(temp1.val <= temp2.val){ //较小的节点放入链表
temp.next = temp1;
temp1 = temp1.next;
}else{
temp.next = temp2; //较小的节点放入链表
temp2 = temp2.next;
}
temp = temp.next;
}
if(temp1 != null){ //一个链表遍历完,相邻链表剩下的一个节点存入新链表
temp.next = temp1;
}
if(temp2 != null){
temp.next = temp2;
}
return list.next; //返回升序链表
}
}
提交结果: