Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode 148. Sort List #44

Open
Woodyiiiiiii opened this issue May 7, 2020 · 0 comments
Open

LeetCode 148. Sort List #44

Woodyiiiiiii opened this issue May 7, 2020 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

Woodyiiiiiii commented May 7, 2020

Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

这道题要求在O(nlogn)的时间复杂度和常数空间复杂度下完成排序。
显然想到使用归并排序(类似)法。二分完后通过实现两个链表的有序合并完成排序。

class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }   
        // divide and conquer
        
        // 1.find middle node
        ListNode mid = head;
        // 注意right不是头节点,是下下一个,保持"2倍"
        // if (right == head) ,错误,会出现栈溢出
        ListNode right = head.next.next;
        ListNode left = head;
        while (right != null && right.next != null) {
            mid = mid.next;
            right = right.next.next;
        }
        
        // 2.divide
        right = mid.next;
        mid.next = null;
        
        // 3.recursive
        left = sortList(left);
        right = sortList(right);
        
        // 4.merge(conquer)
        return merge(left, right);
    }
    private ListNode merge(ListNode l1, ListNode l2) {
        // 按照PDF的设立dummy节点方法
        // eliminate 
        if (l1 == null && l2 == null) {
            return null;
        } 
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        
        ListNode dummy = new ListNode(0);
        ListNode n = dummy;
        ListNode next = null;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                next = l1.next;
                n.next = l1;
                l1.next = null;
                l1 = next;
            }
            else {
                next = l2.next;
                n.next = l2;
                l2.next = null;
                l2 = next;
            }
            n = n.next;
        }
        
        if (l1 != null) {
            n.next = l1;
        }
        if (l2 != null) {
            n.next = l2;
        }
        
        return dummy.next;
        
//         // 按照书上分主副链表进行合并的方法
//         // eliminate 
//         if (l1 == null && l2 == null) {
//             return null;
//         } 
//         if (l1 == null) {
//             return l2;
//         }
//         if (l2 == null) {
//             return l1;
//         }
        
//         // merge
//         // 1.find main and deputy node head
//         ListNode newHead = l1.val <= l2.val ? l1 : l2;
//         ListNode n1 = newHead;
//         ListNode n2 = n1 == l1 ? l2 : l1;
//         // 2.begin
//         while (n1 != null && n2 != null) {
//             // !!!!是n1.next进行判断!!注意逻辑
//             if (n1.next != null && n1.next.val <= n2.val) {
//                 n1 = n1.next;
//             }
//             else {
//                 ListNode next = n2.next;
//                 n2.next = n1.next;
//                 n1.next = n2;
//                 n1 = n2;
//                 n2 = next;
//             }
//         }
//         // n1 != null 不做处理
//         // 注意是if,不是while
//         if (n2 != null) {
//             n1.next = n2;
//         }
        
//         return newHead;
    }
}

分为三个步骤(考点):1.找到中间节点;2.递归二分链表;3.链表合并排序


参考资料:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant