剑指 Offer II 021. 删除链表的倒数第 n 个结点
简单链表预处理长度,也可以用栈 或 双指针(
i
i
i 先走
n
n
n 个,然后
i
i
i 与
j
j
j 一起走直到
i
i
i 到空指针)来做
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int sz = 0;
ListNode res(0,head), *t = head;
while(t){
sz++;
t = t->next;
}
t = head;
ListNode *tmp = &res;
for(int i = 0; i < sz-n; i++, t = t->next, tmp = tmp->next) ;
tmp->next = t->next;
return res.next;
}
};
剑指 Offer II 022. 链表中环的入口节点
哈希表做法
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *t = head, flag(0);
unordered_map<ListNode*,bool> um;
while(t) {
if(!um.count(t)) um[t] = true;
else return t;
t = t->next;
}
return nullptr;
}
};
快慢指针做法
f
a
s
t
fast
fast 走两步,
s
l
o
w
slow
slow 走一步,直到
f
a
s
t
fast
fast 与
s
l
o
w
slow
slow 相遇说明链表存在环。
在相遇时,通过数学关系得到
s
l
o
w
slow
slow 到环入口点+n圈环的距离刚好等于链表头到环入口点距离
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast = head, *slow = head;
while(fast) {
slow = slow->next;
if(fast->next == nullptr) return nullptr;
fast = fast->next->next;
if(fast == slow) {
auto ptr = head;
while(ptr != slow) {
ptr = ptr->next;
slow = slow->next;
}
return ptr;
}
}
return nullptr;
}
};
- t1走完A,走B
- t2走完B,走A
情况一、不相交
他们最后都会同时到nullptr而结束循环。
情况二、相交
最后同时到达相交点
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *t1 = headA, *t2 = headB;
while(t1 != t2){
t1 = t1 == nullptr? headB: t1->next;
t2 = t2 == nullptr? headA: t2->next;
}
return t1;
}
};