您的位置:首页 > 其它

LeetCode Linked List Cycle II

2015-05-16 09:56 337 查看
找链表中的环,如果有则输出环内第一个元素。

经典面试解法是两个指针,7ms过。(不知道那些6ms是怎么办到的,而且还有40%。。。。)

证明理解清楚。设环中节点n个,环外节点m个,则循环中遍历了(m + (n - m%n) + m)个节点。

第一部分为慢指针到达环内第一个元素的步数;第二部分为快指针赶上慢指针的步数;第三部分为找环内第一个元素的步数。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *f1 = head, *f2 = head;
while (f2 && f2->next) { // 忽略掉判断f1,因为慢指针一定不为空(这一步从13ms提速到7ms)
f1 = f1->next; // 如果f1和f2一开始都是head,则更新f1和f2(这两行)不能放入for循环的第三部分(此处WA)
f2 = f2->next->next;
if (f1 == f2) {
for (f1 = head ; f1 != f2 ; f1 = f1->next, f2 = f2->next);
return f1;
}
}
return NULL;
}
如果是Naive解法,则用hash保存每一个指针。用了10ms。估计是自己的bhash写丑了。。。。

struct Mystruct {
struct ListNode* key;
struct B_HashHandle hh;
};
struct ListNode *detectCycle(struct ListNode *head) {
struct B_HashTable* ht = hashInit(struct Mystruct);
struct Mystruct my[16384];
int t = 0;
while (head) {
my[t].key = head;
struct Mystruct* ret = hashSafeInsertField(ht, my[t], key);
if (ret)
return ret->key;
t++;
head = head->next;
}
hashDestroy(ht);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LeetCode 链表