21. Merge two ordered linked lists ●

21. Merge two ordered linked lists ●

describe

Merge two ascending lists into a new ascending list and return. The new linked list is formed by splicing all the nodes of the given two linked lists.

example

insert image description here
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]

answer

1. Recursion

Ideas:

Return the node with the smallest value among the nodes to be merged each time, and point the next pointer of the node to the node with the smallest value among the remaining nodes...

The termination condition is: when a linked list with empty nodes is encountered, directly return the head node of another linked list (there is no need to merge the two linked lists at this time).

  • Time complexity: O ( n + m ) O(n+m)O ( n+m ) , where n and m are the lengths of the two linked lists respectively. Because each recursive call will remove the head node of l1 or l2 (until at least one linked list is empty), the function mergeTwoList will only recursively call each node once at most. Therefore, the time complexity depends on the length of the merged linked list, which is O(n+m).
  • Space Complexity: O ( n + m ) O(n+m)O ( n+m ) , where n and m are the lengths of the two linked lists respectively. Stack space is consumed when recursively calling the mergeTwoLists function, and the size of the stack space depends on the depth of the recursive call. The mergeTwoLists function is called at most n+m times at the end of the recursive call, so the space complexity is O(n+m).
class Solution {
    
    
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
    
    
        if(list1 == nullptr){
    
    
            return list2;				// 遇到空链表,无需合并,直接返回非空链表
        }else if(list2 == nullptr){
    
    
            return list1;
        }else if(list1->val < list2->val){
    
    
            list1->next = mergeTwoLists(list1->next, list2);	// 递归寻找下一个最小值节点
            return list1;										// 返回当前待合并节点的最小值节点
        }else{
    
    
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        }
    }
};

2. Iteration

Link each node in place to achieve merging. When the linked list is not empty, point the next pointer of the prev node to a node with a smaller value, and update the position of the node;

When a linked list is empty, directly link the next node to the non-empty linked list.

At this time, it is necessary to use the virtual head node (sentry node) to assist in recording the real head node.

  • Time complexity: O ( n + m ) O(n+m)O ( n+m ) , where n and m are the lengths of the two linked lists respectively. Because only one element of l1 and l2 will be put into the combined linked list in each loop iteration, the number of while loops will not exceed the sum of the lengths of the two linked lists. All other operations have constant time complexity, so the total time complexity is O(n+m).
  • Space complexity: O ( 1 ) O(1)O ( 1 ) . We only need constant space for a few variables.
class Solution {
    
    
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
    
    
        ListNode* dummyHead = new ListNode(-1);
        ListNode* prev = dummyHead;
        while(list1 != nullptr && list2 != nullptr){
    
    
            if(list1->val < list2->val){
    
    				
                prev->next = list1;						// 将 prev->next 指向数值更小的节点
                list1 = list1->next;					// 移动待合并头结点
            }else{
    
    
                prev->next = list2;
                list2 = list2->next;
            }
            prev = prev->next;							// 更新 prev 节点
        }
        prev->next = list1 == nullptr? list2 : list1;	// 链接剩余的非空链表
        return dummyHead->next;
    }
};

Guess you like

Origin blog.csdn.net/qq_19887221/article/details/126365860