这两题其实是一个思路
因为是有序链表,所以解释起来就比较简单
比如一个是 12345,另一个是56789;
链表首先我们明确的第一点是什么?看过我播客的都知道,那就是他非常容易拆解下来和合。
那我们不如就把结果放在一条新链上呗。
比较也是依次比较。
那这两条链都是有序的啊,我们肯定是两边最小的开始比啊,这都能想到把?
行,比了。
OK假设a0小,把a0先放在结果那里。
那手里还有b0啊,b0跟谁比呢?
那么问题来了,现在知道的是b1一定比b0大,b1一定放b0后面
那么不知道的是什么呢?是a1和b0的关系吧
也就是我草你最小的都比我大,那你看我在一个呢是不是也比我大?
就是这种想法。
那么这道题自然就出来了。
因为an+1>an,bn+1>bn
我们比较an 和 bn ,看看谁小,谁就先放在新链上
同时谁小,谁就往后拿一个
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2)
{
ListNode vhead(0,nullptr);
ListNode* cur = &vhead;
if(list1==nullptr&&list2 ==nullptr){return vhead.next;}
while(list1!=nullptr&&list2!=nullptr)
{
if(list1->val < list2->val)
{
cur->next = list1;
list1 = list1->next;
}
else
{
cur->next = list2;
list2 = list2->next;
}
cur = cur->next;
cur->next = nullptr;
}
if(list1==nullptr) cur->next = list2;
if(list2==nullptr) cur->next = list1;
return vhead.next;
}
};
那么你看这里,关于判断谁大谁小,我们得拿到指针,根据指针指向的val,判断各自的val,同时还得分情况讨论
这里其实很明显的一点是我们有一个盘子
盘子上两块区域,两个链表的人分别吧自己东西放在上面,比谁更小
谁更小就先把更小的放进结果箱子,然后自己再拿下一个继续比
就是这样的擂台赛的感觉有没有?双方直到一方没人了
比赛才结束。
那我们可不可以维护一个【擂台】?
这个擂台可以让两方自动上人,自动比
那么这就是优先级队列。
同时我们还得给擂台指定我们自己的【规则】!
以这样的方式分出胜负。
这就是仿函数。把这个【规则】传给【擂台】,擂台就知道按什么规则决出胜负了。
我们之前学过优先级队列。
也学过仿函数。
我们就先看规则:
class cmp
{
public:
bool operator()(ListNode* a, ListNode* b)
{
return a->val > b->val;
}
};
重载()函数调用符号
把指针放容器和指针后移前必须判断指针是否为空!!!!!
把指针放容器和指针后移前必须判断指针是否为空!!!!!
把指针放容器和指针后移前必须判断指针是否为空!!!!!
class Solution
{
public:
ListNode *mergeKLists(vector<ListNode *> &lists)
{
class cmp
{
public:
bool operator()(ListNode* a, ListNode* b)
{
return a->val > b->val;
}
};
priority_queue<ListNode *, vector<ListNode *>, cmp> pq;
for(int i = 0; i < lists.size(); i++)
{
if(lists[i] != nullptr){
pq.push(lists[i]);
}
}
ListNode* vhead = new ListNode(-1);
ListNode* cur = vhead;
while(!pq.empty())
{
ListNode* top = pq.top();
pq.pop();
cur->next = top;
cur = cur->next;
if(top->next!= nullptr){
pq.push(top->next);
}
}
return vhead->next;
}
};
本题结束!