Merge k Sorted Lists Insertion Sort List Sort List First Missing Positive Sort Colors
147. Insertion Sort List
Sort a linked list using insertion sort.使用直接插入排序将一个链表排序。
因为链表只能向后走,所以插入时,从表头向后插入。注意第一次循环pre和cur指向第一个元素,第二次循环pre和cur才有先后顺序,这样才能保证最后一个节点也参与到排序中来。
另外,头指针p每次内循环都需要回到初始位置。
还有,做插入排序与不做插入排序的结尾pre和cur的处理是不一样的
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode* newHead=new ListNode(0);
ListNode* p=newHead;
newHead->next=head;
ListNode* cur=head;
ListNode* pre=head;//注意这里必须是pre和next的顺序
ListNode* ha=p;
while(cur)
{
if(cur->val<pre->val)
{
pre->next=cur->next;
while(p->next->val<cur->val)
{
p=p->next;
}
ListNode* temp=p->next;
p->next=cur;
cur->next=temp;
cur=pre->next;
p=ha;//需要让p指针再次指向头指针
}
else{
pre=cur;
cur=cur->next;
}
}
p=newHead->next;
delete newHead;
return p;
}
};
148. Sort List
Sort a linked list in O(n log n) time using constant space complexity.
将一个链表排序,要求时间复杂度是O(n log n),空间复杂度是常数。
class Solution {
public:
//使用归并排序
//链表只能使用递归的归并排序方式,首先分解,然后合并
ListNode* sortList(ListNode* head) {
//在开头做递归结束判断
if(!head||!head->next) return head;
//1 分割链表
ListNode* pre,* slow=head,* fast=head;//使用快慢指针找到中间的节点(slow指向它)
while(fast&&fast->next)
{
pre=slow;
slow=slow->next;
fast=fast->next->next;
}
pre->next=nullptr;//两个链表分割
//2 递归分割
ListNode* l1=sortList(head);//递归调用
ListNode* l2=sortList(slow);
//3 合并
return merge(l1,l2);
}
ListNode* merge(ListNode* l1,ListNode* l2){//保证传进来的一定是非空链表
ListNode* newhead=ListNode(0);//定义一个头结点
ListNode* p=newHead;//使用一个指针操作头结点,保存头结点的位置
while(l1&&l2)
{
if(l1->val<l2->val)
{
p->next=l1;
l1=l1->next;
}
else
{
p->next=l2;
l2=l2->next;
}
p=p->next;
}
if(l1) p->next=l1;
if(l2) p->next=l2;
return newHead->next;//返回合并之后的链表
}
};
41. First Missing Positive
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
桶排序
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
for(int i=0;i<nums.size();i++)//桶排序
{
while(nums[i]>0&&nums[i]<=nums.size()&&nums[i]!=i+1&&nums[i]!=nums[nums[i]-1])
swap(nums[i],nums[nums[i]-1]);
}
for(int i=0;i<nums.size();i++)
{
if(nums[i]!=i+1)
return i+1;
}
return nums.size()+1;
}
};
23. Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
使用优先级队列和堆排序
349. Intersection of Two Arrays
Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1]
, nums2 = [2, 2]
, return [2]
.
Note:
- Each element in the result must be unique.
- The result can be in any order.
350. Intersection of Two Arrays II
Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1]
, nums2 = [2, 2]
, return [2, 2]
.
Note:
- Each element in the result should appear as many times as it shows in both arrays.
- The result can be in any order.
Follow up:
- What if the given array is already sorted? How would you optimize your algorithm?
- What if nums1's size is small compared to nums2's size? Which algorithm is better?
- What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?