第九题:链表环路
我的思路:
遍历所有节点,不断存进unordered_set,如果unordered_set里面count出节点2次,那么说明有环(emplace可以用于插入)
代码:
ListNode* cur=head;
unordered_set<ListNode*> ocur={};
while(cur!=NULL){
if(!ocur.count(cur)) ocur.emplace(cur);
else return cur;
cur=cur->next;
}
return NULL;
官方思路(进阶):快慢指针
❄证明:1、快慢指针一定会相遇,且此时快指针(每次2步)一定走了n圈,慢指针(每次1步)还未满1圈
当快慢指针相遇的时候
快指针路程s1:a+n*(b+c)+b
慢指针路程s2:a+b
所以s1=2s2
→a=(n-1)(b+c)+c
→a为n-1圈+c
→当快慢指针相遇的时候,让ptr指针从a开始走,步长为1,慢指针也继续走
当ptr达到入环点(交点)的时候,慢指针也走了n-1圈+c,最终到达入环点
♥统一往顺时针方向走
第十题:栈的最小值(要求时间复杂度为O(1))
别人的思路:
→利用C++原有的栈,题目要求O(1)
→所以不可能通过遍历的时候来知道最小值
→因此要在插入的时候,就把最小值也给记住
→每个栈的存储的数据形式应该是(数值,min)
❄此处min是栈底到其本身之间的最小值
class MinStack {
private:
stack<pair<int,int>> S;//栈中存储(元素,栈底到其本身之间的最小值)---栈顶的second就是全栈最小值
public:
MinStack() {
}
void push(int x) {
if(S.empty()) S.emplace(x,x);//栈空的时候最小值:插入值
else S.emplace(x,min(S.top().second,x));//栈不空的时候最小值:插入值和已经入栈的最小值
}
void pop() {
S.pop();
}
int top() {
return S.top().first;
}
int getMin() {
return S.top().second;
}
};