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.
- 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
- 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
- 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 |
- Define a working pointer to be equal to the head pointer.
- 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
- 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;
- 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
- The idea of recursion is the same task but different parameters.
- 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++.
- Define the right boundary of 0 and the left boundary of 2. The while loops until i>j.
- 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
- 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 |
- 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
- 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
- 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