题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:
z这种题直接引入Python list进行遍历存储,简直不能再省心。
参考答案:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if not pHead:
return None
temp = []
while pHead:
if pHead in temp:
return pHead
else:
temp.append(pHead)
pHead = pHead.next
return None
上述方法省心归省心,就是空间复杂度太高,况且这类题如果都用这种方式的话其实已经没有任何算法逻辑可言了,下面补充一种正规思路,其空间复杂度为 O(1),思路见 LeetCode 的链表环入口,下面只提供代码:
C++ version:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead == nullptr){
return NULL;
}
ListNode* p1 = pHead;
ListNode* p2 = pHead->next;
while(p2){
p1 = p1->next;
p2 = p2->next;
if(p1 == p2){
break;
}
if(p2){
p2 = p2->next;
}
}
if(p2 == nullptr){
return NULL;
}
p1 = pHead;
while(p1 != p2){
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
};
Note
- 上述代码中值得借鉴的是第一轮判定是否存在环时候的快慢指针判定:
while(p2){
p1 = p1->next;
p2 = p2->next;
if(p1 == p2){
break;
}
if(p2){
p2 = p2->next;
}
}
其中,对 p2 快指针,再次判定 if(p2)
,思路清晰,简单易懂。