Sorting Special_Quick Sort_Merge Sort

Sorting Special_Quick Sort_Merge Sort

1. Combine two ordered linked lists

Title description

https://leetcode-cn.com/problems/merge-two-sorted-lists/

Problem solving ideas

Idea 1: Iteration: Two for traverse two linked lists, compare the value of val, and point to the smaller number one by one.

  1. Compare the sizes of the i-th and j-th elements of the two linked lists in turn, and create a new working node prev, the previous node when the size was compared last time, pointing to the node corresponding to the smaller number after the comparison.

Idea 2: Recursion

  1. Compare the size of the current node of the two linked lists, and record that the smaller node in the first comparison is returned as the head node. And make the smaller node point to this function recursively (smaller node->next, another node): the next recursive task.

Source code

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    
    
        if(!l1)
        {
    
    
            return l2;
        }
        if(!l2)
        {
    
    
            return l1;
        }
        ListNode* head = new ListNode(-1);
        // 迭代是需要一个工作节点的,这里定义一个指针等于另外一个指针(同一类型的指针)
        ListNode* prev = head;
        while(l1 && l2)
        {
    
    
            if(l1->val <= l2->val)
            {
    
    
                prev->next = l1;
                l1 = l1->next;
            }
            else
            {
    
    
                prev->next = l2;
                l2 = l2->next;
            }
            prev = prev->next;
        }
        prev->next = l1 ? l1 : l2;
        return head->next;
    }
};

Idea 2:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    
    
        if(!l1)
        {
    
    
            return l2;
        }
        if(!l2)
        {
    
    
            return l1;
        }
        if(l1->val <= l2->val)
        {
    
    
        	l1->next = mergeTwoLists(l1->next, l2);
        	return l1;
		}
		else
		{
    
    
			l2->next = mergeTwoLists(l2->next, l1);
			return l2;
		}
    }
};

Question analysis

  1. The merge sorting problem can be solved by recursive and iterative methods, and the time complexity of the recursive method is much lower.

What should I pay attention to next time I encounter this kind of question

easy in difficult
tight 1. The idea of ​​recursion is that the next task is the same as this one, except that the parameter values ​​are changed. 2. The idea of ​​iteration may define a working pointer as a record.
General
must
  1. Define a working pointer to be equal to the head pointer.
  2. The next of the head pointer points to the first node of the linked list.

Time and space complexity

Idea 1:
sf: O(m+n)
kf: O©

Idea 2:
sf: O(m+n)
kf: O(m+n), call function recursively

Such question template code

  1. Iteration
ListNode* head = new ListNode(-1);
// 迭代是需要一个工作结点的,这里定义一个指针等于另外一个指针(同一类型的指针)
ListNode* prev = head;
while(l1 && l2)
{
    
    
    if(l1->val <= l2->val)
    {
    
    
        prev->next = l1;
        l1 = l1->next;
    }
    else
    {
    
    
        prev->next = l2;
        l2 = l2->next;
    }
    prev = prev->next;
}
prev->next = l1 ? l1 : l2;
  1. Recursion
if(l1->val <= l2->val)
{
    
    
    l1->next = mergeTwoLists(l1->next, l2);
    return l1;
}
else
{
    
    
    l2->next = mergeTwoLists(l2->next, l1);
    return l2;
}

Enlightenment or universality

  1. The idea of ​​recursion is the same task but different parameters.
  2. The idea of ​​iteration is the traversal of work pointers.

to sum up

Merge sort = recursion (same task, different parameters) / iteration (traversal of work pointer)

2. Color Classification

Title description

https://leetcode-cn.com/problems/sort-colors/

Problem solving ideas

Idea 1: There is a bit of quick sorting idea, define the right boundary of 0 and the left boundary of 2, respectively, traverse the value of the array, and swap with the left boundary of 2 when encountering 2; swap with the left boundary of 0 when encountering 0 ; When encountering 1, then i++.

  1. Define the right boundary of 0 and the left boundary of 2. The while loops until i>j.
  2. Swap with the left boundary of 2 when it encounters 2, swap with the left boundary of 0 when it encounters 0, and i++ when it encounters 1.

Source code

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int len = nums.size();
        // 0的右边界 
        int le = 0;
        int ri = len - 1;
        int i = 0;
        while(i <= ri)
        {
        	if(nums[i] == 0)
        	{
        		int tmp = nums[i];
        		nums[i++] = nums[le];
        		nums[le++] = tmp;
			}
			else if(nums[i] == 2)
        	{
        		int tmp = nums[i];
        		nums[i] = nums[ri];
        		nums[ri--] = tmp;
			}
			else{
				i++;
			}
		}
    }
};

Question analysis

  1. The essence of fast sorting: using a recursive function, starting from the number a[i] on the left of the array, put the number of the array in a suitable position (traverse the number larger than a[i] from the left, and traverse from the right than a[i] [i] Small number, exchange); After placing a[i] in a suitable position, the number on the left of a[i] is less than a[i], the number on the right is greater than a[i], and then the left is also used faster Row until i>j.

What should I pay attention to next time I encounter this kind of question

easy in difficult
tight 1. The essence of fast sorting: put the number on the left of the reference number (range) to a suitable position, and then recursively sort the left and right of this position.
General
must
  1. Note that when traversing to 2, the traversed index does not need to be +1, because the number that may be exchanged has not been placed in the correct position. When traversing to 0, the index of the traversal can be +1, because the traversal starts from position 0 of the array, so the a[le] element on the left is ordered.

Time and space complexity

Thought 1:
sf: O (n)
kf: O (1)

Thought 2:
sf: O ()
kf: O ()

Such question template code

  1. Quick sort code.
int le = 0;
int ri = len - 1;
int i = 0;
while(i <= ri)
{
    
    
    if(nums[i] == 0)
    {
    
    
        int tmp = nums[i];
        nums[i++] = nums[le];
        nums[le++] = tmp;
    }
    else if(nums[i] == 2)
    {
    
    
        int tmp = nums[i];
        nums[i] = nums[ri];
        nums[ri--] = tmp;
    }
    else{
    
    
        i++;
    }
}

Enlightenment or universality

  1. The recursive nature of quicksort: keep placing a number in an appropriate position in an interval.

to sum up

Color classification = tricolor problem + fast sorting (left and right boundary of the interval + placed in a suitable position)

Title description

Problem solving ideas

Idea 1:

Source code

Question analysis

What should I pay attention to next time I encounter this kind of question

easy in difficult
tight
General
must

Time and space complexity

Thought 1:
sf: O ()
kf: O ()

Thought 2:
sf: O ()
kf: O ()

Such question template code


Enlightenment or universality

to sum up

Guess you like

Origin blog.csdn.net/qq_40092110/article/details/106154375