力扣题目
解题思路
java代码
力扣题目:
给你链表的头结点 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
解题思路:
方法 sortList(ListNode head)
:
这是一个递归方法,用于对链表进行排序。它实现了归并排序算法,适用于链表结构。以下是详细的步骤:
-
递归终止条件:
- 如果链表为空 (
head == null
) 或者链表只有一个节点 (head.next == null
),则直接返回头节点。
- 如果链表为空 (
-
找到中间节点:
- 使用快慢指针法找到链表的中间节点。快指针
fast
每次移动两步,慢指针slow
每次移动一步。当fast
到达链表末尾时,slow
将位于链表中间。
- 使用快慢指针法找到链表的中间节点。快指针
-
分割链表:
- 将链表从中间节点分割成两个子链表。
tmp
指向右半部分的头节点,而slow.next
被设置为null
,断开左半部分和右半部分的连接。
- 将链表从中间节点分割成两个子链表。
-
递归排序子链表:
- 递归地对左半部分 (
head
) 和右半部分 (tmp
) 进行排序。
- 递归地对左半部分 (
-
合并排序后的链表:
- 创建一个哑节点
h
(其val
可以是任意值,这里设置为 0),并使用res
指向它。然后,比较左右子链表的节点值,将较小的节点连接到h
的后面,并移动h
指针。 - 当其中一个子链表为空时,将另一个子链表剩余的部分连接到
h
的后面。
- 创建一个哑节点
-
返回排序后的链表:
res.next
指向排序后的链表的头节点,因此返回res.next
。
java代码:
package org.example.mouth7.taday18;
public class Leetcode148 {
public static void main(String[] args)
{
ListNode head = new ListNode(4);
head.next = new ListNode(2);
head.next.next = new ListNode(1);
head.next.next.next = new ListNode(3);
ListNode res = sortList(head);
while (res != null)
{
System.out.println(res.val);
res = res.next;
}
}
public static ListNode sortList(ListNode head)
{
if (head == null || head.next == null)
{
return head;
}
ListNode fast = head.next;
ListNode slow = head;
while (fast != null && fast.next != null)
{
fast = fast.next.next;
slow = slow.next;
}
ListNode tmp = slow.next;
slow.next = null;
ListNode left = sortList(head);
ListNode right = sortList(tmp);
ListNode h = new ListNode(0);
ListNode res = h;
while (left != null && right != null)
{
if (left.val < right.val)
{
h.next = left;
left = left.next;
}
else
{
h.next = right;
right = right.next;
}
h = h.next;
}
h.next = left != null ? left : right;
return res.next;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项