Q:Given a circular linked list, implement an algorithm which returnsnode at the beginning of the loop.
A:
思路1:可以用哈希表记录每一个节点,遍历链表,通过哈希表记录判断,如果当前节点已经被访问过,那么有环。如果遍历结束,那么没有loop
思路2:
1、双指针查看是否有环。快指针速度为2, 慢指针速度为1
2、如果有环,则再利用双指针p = head, q = 快慢指针交点; p, q速度都是1, 相等的时候就是loop的起点
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode *init(int a[], int n) {
ListNode *head = NULL;
ListNode *p = NULL;
for (int i = 0; i < n; i++) {
ListNode *cur = new ListNode(a[i]);
if (i == 0) {
head = cur;
p = cur;
}
p->next = cur;
p = cur;
}
return head;
}
ListNode *detectCycle(ListNode *head) {
if (!head) {
return NULL;
}
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
ListNode *slow2 = head;
while (slow2 != slow) {
slow = slow->next;
slow2 = slow2->next;
}
return slow2;
}
}
return NULL;
}
void printList(ListNode *head) {
ListNode *p = head;
for( ; p; p = p->next) {
cout<<p->val<<" ";
}
cout<<endl;
}
int main() {
int a[10] = {2,4,3};
int b[10] = {5,6,4};
ListNode *head1 = init(a, 3);
ListNode *head2 = init(b, 3);
printList(head1);
printList(head2);
ListNode *head = addTwoNumbers(head1, head2);
printList(head);
return 0;
}