题目:在O(n log n)的时间内使用常数级空间复杂度对链表进行排序。
思路:由于题目要求,时间复杂度要求为O(n log n),所以,需要用归并排序。
- 找到链表的中间节点
- 通过中间节点将链表1分为2
- 两个链表进行比较,比较完之后进行合并。
代码:
package com.company;
import java.util.List;
public class TestNo24 {
//定义单链表
static class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
next = null;
}
public String toString(){
if(this.next == null){
return String.valueOf(this.val);
}
return this.val + "->" + this.next.toString();
}
}
public static void main(String[] args) {
TestNo24 t = new TestNo24();
ListNode head = new ListNode(4);
head.next = new ListNode(5);
head.next.next= new ListNode(7);
head.next.next.next = new ListNode(9);
head.next.next.next.next = new ListNode(10);
head.next.next.next.next.next = new ListNode(1);
head.next.next.next.next.next.next = new ListNode(2);
// 下面是产生连续的链表
// ListNode head = createTestLinkList();
// ListNode newHead = new ListNode(13);
//newHead.next = head;
System.out.println(head);
System.out.println(t.sortList(head));
}
private static ListNode createTestLinkList(){
ListNode head = new ListNode(0);
ListNode curNode = head;
for(int i = 0;i<10;i++){
curNode.next = new ListNode(i);
curNode = curNode.next;
}
return head;
}
public ListNode sortList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode mid = getMid(head);
ListNode another ;
if(mid == null){
another = null;
}else{
//此时是两个链表,从链表的中间节点分开,中间节点之前之后分别是一个链表
another = mid.next;
mid.next = null;
}
return mergeSortedList(sortList(head),sortList(another));
}
//合并两个有序链表为一个链表
private ListNode mergeSortedList(ListNode first,ListNode second){
if(first == null && second == null){
return null;
}
if(first == null){
return second;
}
if(second == null){
return first;
}
//虚拟一个head的前缀节点
ListNode pre = new ListNode(0);
ListNode curNode = pre;
ListNode cur1 = first;
ListNode cur2 = second;
while (cur1 != null && cur2 !=null){
if(cur1.val <= cur2.val){
curNode.next = cur1;
cur1 = cur1.next;
}else{
curNode.next = cur2;
cur2 = cur2.next;
}
curNode = curNode.next;
}
//处理剩下的节点元素
if(cur1 != null){
curNode.next = cur1;
}else{
curNode.next = cur2;
}
return pre.next;
}
//寻找链表的中间节点,使用快慢两个指针
private ListNode getMid(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next !=null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
来源:CSDN
作者:胡别致
链接:https://blog.csdn.net/qq_40664693/article/details/104263234