LeetCode刷题——排序链表#148#Medium

排序链表题目的思路探讨与源码
    排序链表的题目如下图,该题属于链表和排序类型的题目,主要考察对于归并排序和链表的使用理解和认识。本文的题目作者想到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的快慢指针方法速度一般,应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。

おすすめ

転載: blog.csdn.net/qq_26727101/article/details/118444815