Likou Question 148 - Sorted Linked List

Get into the habit of writing together! This is the 15th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

foreword

Likou No. 148 排序链表is as follows :

Given the head node  of the linked list, sort head it in  ascending  order and return  the sorted linked list  .

Example 1:

输入: head = [4,2,1,3]
输出: [1,2,3,4]
复制代码

1. Ideas

The question is very short, very similar to yesterday's question Likou No. 147 - Insertion Sorting a Linked List , which is to change the list into an ascending order .

If you use yesterday's code directly 插入排序, you can pass this question. In addition, there is a very simple idea as follows:

  1. Traverse the linked list and collect all elements
  2. Sort the collected elements in ascending order
  3. Traverse the linked list again, take the sorted element values ​​in turn, and modify each element

This problem can also be completed like this, but this O(n)requires space to store each node, which cannot meet the advanced requirements of the problem.

image.png

merge sort

How to do it? Since O(N*logN)the time complexity and constant space complexity, it is easy to think of using it 归并排序. The core idea of ​​merge sort is:先拆分,再合并

The example in the head = [4,2,1,3]example is shown here. The principle of splitting is to split according to the middle of the linked list, until there are only two elements in the sub linked list (one element does not need to be reordered, so it is split into two element is fine).

  1. process of splitting

The linked list will eventually be split into two sub-linked lists as follows

image.png

  1. process of merging

The process of merging is to first sort the elements in the sub-linked list, and then merge the sorted sub-linked lists, that is, to merge two linked lists sorted in ascending order .

image.png

In summary, 归并排序the roughly as follows:

  1. Use 递归to split the linked list
  2. Sort child list in ascending order
  3. Between multiple sub-linked lists, merge the linked lists in ascending order

2. Realization

implementation code

The implementation code is consistent with the idea

public ListNode sortList(ListNode head) {
    return dfs(head, null);
}

public ListNode dfs(ListNode head, ListNode tail){
    if (head == null)
        return null;
    if (head.next == tail){
        head.next = null;
        return head;
    }
    // 从中间分割
    ListNode fast = head;
    ListNode slow = head;
    while (fast != tail){
        slow = slow.next;
        fast = fast.next;
        if (fast != tail)
            fast = fast.next;
    }
    ListNode listNode1 = dfs(head, slow);
    ListNode listNode2 = dfs(slow, tail );
    return mergeTwoLists(listNode1, listNode2);

}

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode ret = new ListNode();
    ListNode temp = ret;
    // 迭代
    while (l1 != null && l2 != null) {
        if (l1.val < l2.val) {
            temp.next = l1;
            l1 = l1.next;
        } else {
            temp.next =l2;
            l2 = l2.next;
        }
        temp = temp.next;
    }
    // 将未遍历完的列表归入结果
    if (l1 == null) {
        temp.next = l2;
    }
    if (l2 == null)
        temp.next = l1;
    return ret.next;
}
复制代码

test code

public static void main(String[] args) {
    ListNode list = new ListNode(4, new ListNode(2, new ListNode(1, new ListNode(3))));
    ListNode ret = new Number148().sortList(list);
    System.out.println("test");
}
复制代码

result

image.png

3. Summary

Thank you for watching to the end, very honored to be able to help you~♥

If you think my writing is not bad, please give me a like! If you have any questions, you can also see in the comments section~

Guess you like

Origin juejin.im/post/7086771357521805343