题目:
解答:
cpp
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* fast=head;
struct ListNode* slow=head;
while(fast!=NULL){
slow=slow->next;
if(fast->next!=NULL)
fast=fast->next->next;
else
return NULL;
if(fast==slow){
struct ListNode* p=head;
while (p != slow) {
p = p->next;
slow = slow->next;
}
return p;
}
}return NULL;
}
cpp
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode*> visited;
while(head!=nullptr){//NULL时空整数,nullptr表示空指针
if(visited.count(head)){//计算统计head在集合里面出现几次,出现过即入口指针
return head;
}
visited.insert(head);
head=head->next;
}
return nullptr;
}
};
心得:法一是王道原题,记得当时就是根据快慢指针指向不同而作为解法,abc为三段,快慢相遇时有如下表达式,所以能推算出b。
法二:用哈希指针集合表示,count函数来判定出现的次数,返回nullptr代表无环。
题目:
解答:
cpp
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
int count=0;
struct ListNode* p=head;
struct ListNode* dummy=(struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next=head;
for(p;p!=NULL;p=p->next)
count++;
if(count<n)
return NULL;
p=dummy;
for(int i=0;i<count-n;i++){
p=p->next;
}
struct ListNode* q=p->next;
p->next=p->next->next;
free(q);
return dummy->next;
}
心得:使用哑节点,便于处理头结点,然后找到要删除的点(count-n),删除节点然后释放空间。需要注意的是,dummy需要申请空间,防止变成野指针。
题目:
解答:
cpp
struct ListNode* swapPairs(struct ListNode* head) {
struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next = head;
struct ListNode* prev = dummy;
while(prev->next!=NULL&&prev->next->next!=NULL){
struct ListNode* first=prev->next;
struct ListNode* second=first->next;
prev->next=second;
first->next=second->next;
second->next=first;
prev=first;
}
return dummy->next;
}
心得:我原本想的思路是创建一个新的链表,先指向所有偶次链表节点,然后插入所有奇数链表节点,但是实现起来琐碎且复杂。答案采用直接dummy链接整个head链表,再内部调整两个节点的顺序,代码超级简单,记住这种思路。



