LeetCode Linked List Cycle II

找链表中的环,如果有则输出环内第一个元素。

经典面试解法是两个指针,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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值