BM7 链表中环的入口结点
给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
数据范围: n≤10000n≤10000,1<=结点值<=100001<=结点值<=10000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
思考:
根据阅读题目和样例可知,链表正常情况下按照递增序列排序。
因此仅需记录pre和cur节点,当出现cur<=pre时,即为环入口,返回cur
代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
int pre = -1, cur = pHead->val;
while (pHead->next != nullptr) {
pre = cur;
pHead = pHead->next;
cur = pHead->val;
if (cur <= pre) return pHead;
}
return nullptr;
}
};
BM6 判断链表中是否有环
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
数据范围:链表长度 0≤n≤100000≤n≤10000,链表中任意节点的值满足 ∣val∣<=100000∣val∣<=100000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
输入分为两部分,第一部分为链表,第二部分代表是否有环,然后将组成的head头结点传入到函数里面。-1代表无环,其它的数字代表有环,这些参数解释仅仅是为了方便读者自测调试。实际在编程时读入的是链表的头节点。
思考:
对有环链表进行遍历,会陷入无限循环,因此记录链表长度,当达到最大值的时候,一定存在环
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
int len = 0;
// bool flag = false;
while (head != nullptr) {
head = head->next;
len++;
if (len > 10000) return true;
}
return false;
}
};
BM5 合并k个已排序的链表 ※※※
合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
数据范围:节点总数 0≤n≤50000≤n≤5000,每个节点的val满足 ∣val∣<=1000∣val∣<=1000
要求:时间复杂度 O(nlogn)
思考:
建立一个优先队列,把所有链表的头节点放入队列中。
对优先队列进行遍历,将最小的节点以尾插法的形式插入新链表中,维持升序。
失去最小元素的链表将后续节点加入优先队列中,反复筛选最小节点。
比较器
比较规则说明:
return a->val > b->val表示:
- 当
a->val大于b->val时返回true- 这会导致容器将较小的值放在前面(升序排列)
- 在优先队列中,这会创建一个小顶堆(最小元素在顶部)
- 如果改为
return a->val < b->val:
- 将创建一个大顶堆(最大元素在顶部)
比较器的返回值有两个应用场景,分别是:
1)是否交换两个元素的位置,True并表示不交换
2)表示优先级,True表示前一个元素的优先级更低
struct cmp {
bool operator()(ListNode* a, ListNode* b) {
return a->val > b-> val;
}
};
代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <bits/types/struct_tm.h>
#include <queue>
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param lists ListNode类vector
* @return ListNode类
*/
struct cmp {
bool operator()(ListNode* a, ListNode* b) {
return a->val > b-> val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
// write code here
std::priority_queue<ListNode*, std::vector<ListNode *>, cmp> pq;
for(int i = 0;i < lists.size();i++) if (lists[i] != nullptr) pq.push(lists[i]);
ListNode* res = new ListNode(0);
ListNode* cur = res;
while (!pq.empty()) {
ListNode* tmp = pq.top();
pq.pop();
// 尾插法
cur->next = tmp;
cur = cur->next;
if (tmp->next) pq.push(tmp->next);
}
return res->next;
}
};
1787

被折叠的 条评论
为什么被折叠?



