- 剑指 Offer II 075. 数组相对排序(sort)">剑指 Offer II 075. 数组相对排序(sort)
- 剑指 Offer II 074. 合并区间(需要看)">剑指 Offer II 074. 合并区间(需要看)
- 剑指 Offer II 077. 链表排序(求中点+归并排序)">剑指 Offer II 077. 链表排序(求中点+归并排序)
- 剑指 Offer II 078. 合并排序链表(有意义)">剑指 Offer II 078. 合并排序链表(有意义)
剑指 Offer II 075. 数组相对排序(sort)
对于cmp函数来说,返回true就代表前面应该放在前面,flase则相反。
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2){
unordered_map<int, int> hashset;
for(int i = 0; i < arr2.size(); i++) {
hashset[arr2[i]] = i;
}
sort(arr1.begin(), arr1.end(), [&](int a, int b){
if(hashset.count(a)&&hashset.count(b)) {
return hashset[a] < hashset[b];
} else if(!hashset.count(a)&&!hashset.count(b)){
return a < b;
} else {
if(hashset.count(a)) {//注意这里的特殊写法
return true;
} else {
return false;
}
}
});
return arr1;
}
};
剑指 Offer II 074. 合并区间(需要看)
要把很多情况都分清楚
这里以第一个区间作为排序标准比较好。更加方便比较class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> ret;
vector<int> ser = intervals[0];
for(int i = 1; i < intervals.size() ; i++) {
if(ser[1] < intervals[i][0]) {
ret.push_back(ser);
ser.clear();
} else {
if(ser[1] <= intervals[i][1]) {
ser[1] = intervals[i][1];
}
}
if(ser.size() == 0) {
ser = intervals[i];
}
}
if(ser.size()) {
ret.push_back(ser);
}
return ret;
}
};
剑指 Offer II 077. 链表排序(求中点+归并排序)
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(!head||!head->next) return head;
ListNode* mid = getmid(head);
ListNode* node = mid->next;
mid->next = nullptr;
ListNode* node1 = sortList(head),* node2 = sortList(node);
ListNode* dummy = new ListNode(0);
ListNode* ret = dummy;
while(node1&&node2) {
if(node1->val < node2->val) {
ret ->next = node1;
node1 = node1->next;
} else {
ret ->next = node2;
node2 = node2->next;
}
ret = ret->next;
}
//尾巴接上去
if(!node1) {
ret->next = node2;
} else {
ret->next = node1;
}
return dummy->next;
}
ListNode* getmid(ListNode* head) {//根据快慢指针获取中点
ListNode* fast = head, *slow = head;
while(fast->next&&fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
剑指 Offer II 078. 合并排序链表(有意义)
归并排序
和上题目的写法类似,但是复杂度过高
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* dummy = new ListNode(0);
ListNode* ret = dummy, *node;
while((node = getnode(lists))) {
ret->next = node;
ret = ret->next;
}
return dummy->next;
}
ListNode* getnode(vector<ListNode*>& lists) {
ListNode* node = nullptr;
int idx = 0;
for(int i = 0; i < lists.size(); i++) {
if(!lists[i]) continue;
if(!node) {
node = lists[i];
idx = i;
} else {
if(node->val > lists[i]->val) {
node = lists[i];
idx = i;
}
}
}
if(node) {
lists[idx] = lists[idx]->next;
}
return node;
}
};
堆排序
千万注意priority_queue的cmp逻辑是反着来的,node1->val < node2->val是大顶堆,node1->val > node2->val 才是小顶堆。
- 默认为大顶堆
class Solution {
public:
struct cmp {
bool operator()(ListNode* node1, ListNode* node2) {//仿函数写cmp
return node1->val > node2->val;//这里是小顶堆,因为优先队列就是这样设计的,和正常逻辑相反
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp> q;
for(auto list : lists) {
if(!list) continue;
q.push(list);
}
ListNode *dummy = new ListNode(0);
ListNode *ret = dummy;
while(!q.empty()) {
ListNode* node = q.top();
q.pop();
if(node->next) q.push(node->next);
ret->next = node;
ret = ret->next;
}
return dummy->next;
}
};