[33] Sorted Linked List | Intersected Linked List (LeetCode 148 | 160)

Sorted list

Problem Description

Give you the head node of the linked list, please sort it in ascending order and return to the sorted linked list.

Advanced:

Can you sort the linked list in O(n log n) time complexity and constant level space complexity?

Problem-solving ideas

Seeing the time complexity of O (nlogn), the first idea is quick sort, but the pointer cannot move forward, so you can't use quick sort in this question. Instead, merge sort should be used.
Insert picture description here
If you want to achieve the constant time space complexity required by the problem, use iteration to achieve it.

For merge sort, see merge sort (merge sort)-divide and conquer-computer algorithm .

First look at the recursive method:

  1. Find the middle node mid of the linked list; (use the speed pointer, you can also find the length of the linked list to find the node at n/2)
  2. Sort the upper part and the lower part; (the method of sorting each part is still to find the intermediate node, sort by part, and merge)
  3. Merge the two parts in order. (See merging two ordered linked lists )

Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* sortList(ListNode* head, ListNode* tail) {
    
    //分治排序
        if (!head) 
            return head;
        if (head->next == tail) {
    
    //还剩一个结点时直接返回
            head->next = nullptr;
            return head;
        }
        ListNode* slow = head, *fast = head;
        while (fast != tail) {
    
    //找中间位置的结点
            slow = slow->next;
            fast = fast->next;
            if (fast != tail) {
    
    
                fast = fast->next;
            }
        }
        ListNode* mid = slow;
        ListNode* p = sortList(head, mid);
        ListNode* q = sortList(mid, tail);
        return merge(p,q);
    }

    ListNode* merge(ListNode* l1, ListNode* l2) {
    
     //递归合并两个有序链表
        if (l1 == nullptr) {
    
    
            return l2;
        } else if (l2 == nullptr) {
    
    
            return l1;
        } else if (l1->val < l2->val) {
    
    
            l1->next = merge(l1->next, l2);
            return l1;
        } else {
    
    
            l2->next = merge(l1, l2->next);
            return l2;
        }
    }

    ListNode* sortList(ListNode* head) {
    
    
        return sortList(head, nullptr);
    }
};

Intersecting linked list

Problem Description

Write a program to find the starting node where two singly linked lists intersect.

example:
Insert picture description here

Problem-solving ideas

① Find the length difference between the linked list a and the linked list b;
② Point the pointers of A and B to the same level according to the length difference; ③ Move the pointers of A and B
backwards until they point to the same position or NULL.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    int legth(ListNode* head){
    
    //求链表的长度
        int i=0;
        while(head){
    
    
            i++;
            head = head->next;
        }
        return i;
    }

    ListNode *res(ListNode *headA,ListNode *headB){
    
    //返回结果
        ListNode* res = NULL;
        while(headA && headB){
    
    
            if(headA == headB){
    
    
                res = headA;
                break;
            }
            headA = headA->next;
            headB = headB->next;
        }
        return res;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        if(headA == headB) return headA;
        if(!headA || !headB) return NULL;

        int an = legth(headA),bn = legth(headB);
        if(an > bn){
    
    
            int cha = an-bn;
            for(int i=0;i<cha;i++) //将A、B指针指向同一水平
                headA = headA->next;
            return res(headA,headB);
        }else{
    
    
            int cha = bn-an;
            for(int i=0;i<cha;i++)
                headB = headB->next;
            return res(headA,headB);
        }
    }
};

Time complexity: O(n)
Space complexity: O(1)

Guess you like

Origin blog.csdn.net/qq_43424037/article/details/113689197