排序链表题目的思路探讨与源码
排序链表的题目如下图,该题属于链表和排序类型的题目,主要考察对于归并排序和链表的使用理解和认识。本文的题目作者想到1种方法,也就是通过快慢指针实现的归并排序。代码使用java写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用基于快慢指针的归并排序算法。由于题目本身要求使用O(nlog(n))时间复杂度的算法,所以只有快速排序和归并排序算法,而本人只会实现归并排序算法,所以在此处只介绍这种算法。我们首先要找到链表的中点,以中点为分界,将链表拆分成两个子链表。而寻找链表的中点需要使用快慢指针,快指针每次移动2步,慢指针每次移动1步,而当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。然后我们在拆分得到两个子链表后对它们分别进行排序,最后把两个有序的链表合并,得到1个新的有序的链表。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public ListNode sortList(ListNode head) {
return sortList(head, null);
}
public ListNode sortList(ListNode begin, ListNode end) {
if (begin == null) {
return begin;
}
if (begin.next == end) {
begin.next = null;
return begin;
}
ListNode a = begin;
ListNode b = begin;
while (a != end) {
a = a.next;
b = b.next;
if (a != end) {
a = a.next;
}
}
ListNode medium = b;
ListNode one = sortList(begin, medium);
ListNode two = sortList(medium, end);
ListNode sorted = merge(one, two);
return sorted;
}
public ListNode merge(ListNode one, ListNode two) {
ListNode first = new ListNode(0);
ListNode flag = first;
ListNode flag1 = one;
ListNode flag2 = two;
while (flag1 != null && flag2 != null) {
if (flag1.val <= flag2.val) {
flag.next = flag1;
flag1 = flag1.next;
} else {
flag.next = flag2;
flag2 = flag2.next;
}
flag = flag.next;
}
if (flag1 != null) {
flag.next = flag1;
} else if (flag2 != null) {
flag.next = flag2;
}
return first.next;
}
}
从结果来说基于java的快慢指针方法速度一般,应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。