leetcode题目:Linked List Cycle和Linked List Cycle II

题目一:

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

题目二:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:
Can you solve it without using extra space?

两个题目是类似的。只是在第二题中需要返回节点地址。

解题思路:

思路1)用一个集合(set)去存取遍历过程中的地址。在每次遍历过程中查找此集合中是否已经存在该值,若存在,则存在循环。

思路2)用两个指针,一个快指针,一个慢指针。若存在循环,则两个指针时钟会相遇。

其中思路1)需要额外的空间。

题目一代码:

只采用思路2)的方式:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* pNode = head;
		if(pNode == NULL)
		{
			return false;
		}
		ListNode* pNextNode = head;
		while (pNextNode && pNextNode->next)
		{
			pNode = pNode->next;
			pNextNode = pNextNode->next->next;
			if(pNode == pNextNode)
				return true;
		}
		return false;
    }
};

对于题目二:

思路一是比较简洁的,但是需要额外的内存空间,不符合题目要求。但是系统还是给你通过了。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* pNode = head;
        set<ListNode*>m_vec;
		while (pNode)
		{
			if(m_vec.find(pNode)==m_vec.end())
			{
				m_vec.insert(pNode);
			}
			else
			{
				return pNode;
			}
			pNode = pNode->next;
		}
        return NULL;
    }
};

当然,该题还是可以应用思路二。

可以想象:

当存在循环时,快指针和慢指针会相遇。此时加入另一个指针,取名为延迟指针,该指针从链表头开始,跟慢指针同一样的脚步前进。他们就肯定会在循环入口点地址相遇。

代码实现如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* pNextNode = head;
        ListNode* pNode = head;
        while(pNextNode && pNextNode->next)
        {
            pNode = pNode->next;
            pNextNode = pNextNode->next->next;
            if(pNode==pNextNode)
            {
                ListNode* pReNode = head;
                while(pReNode!=pNode)
                {
                    pReNode = pReNode->next;
                    pNode = pNode->next;
                }
                return pReNode;
            }
        }
        return NULL;
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值