55、给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:设定两个指针,一个慢指针,一个快指针,快指针的速度是慢指针的两倍,然后呢,如果有环,他们一定会在环中相遇。
C++
/*
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 nullptr;
ListNode* p1=pHead;
ListNode* p2=pHead;
while(p1->next!=nullptr&&p2->next->next!=nullptr)
{
p1=p1->next;
p2=p2->next->next;
if(p1==p2)
{
p1=pHead;
while(p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
return p1;
}
}
return nullptr;
}
};
python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
p1=p2=pHead;
while(p1.next!=None and p2.next.next!=None):
p1=p1.next
p2=p2.next.next
if p1==p2:
p1=pHead
while(p1!=p2):
p1=p1.next
p2=p2.next
return p1
return None
36、输入两个链表,找出它们的第一个公共结点。
思路1:我们可以把两个链表拼接起来,一个pHead1在前pHead2在后,一个pHead2在前pHead1在后。这样,生成了两个相同长度的链表,那么我们只要同时遍历这两个表,就一定能找到公共结点。时间复杂度O(m+n),空间复杂度O(m+n)。
思路2:我们也可以先让把长的链表的头砍掉,让两个链表长度相同,这样,同时遍历也能找到公共结点。此时,时间复杂度O(m+n),空间复杂度为O(MAX(m,n))。
C++思路1
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==nullptr || pHead2==nullptr)
return nullptr;
ListNode *p1=pHead1;
ListNode *p2=pHead2;
while (p1 != p2)
{
p1=(p1==nullptr?pHead2:p1->next);
p2=(p2==nullptr?pHead1:p2->next);
}
return p1;
}
};
C++思路2:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
// 如果有一个链表为空,则返回结果为空
if(pHead1 == NULL || pHead2 == NULL){
return NULL;
}
// 获得两个链表的长度
unsigned int len1 = GetListLength(pHead1);
unsigned int len2 = GetListLength(pHead2);
// 默认 pHead1 长, pHead2短,如果不是,再更改
ListNode* pHeadLong = pHead1;
ListNode* pHeadShort = pHead2;
int LengthDif = len1 - len2;
// 如果 pHead1 比 pHead2 小
if(len1 < len2){
ListNode* pHeadLong = pHead2;
ListNode* pHeadShort = pHead1;
int LengthDif = len2 - len1;
}
// 将长链表的前面部分去掉,使两个链表等长
for(int i = 0; i < LengthDif; i++){
pHeadLong = pHeadLong->next;
}
while(pHeadLong != NULL && pHeadShort != NULL && pHeadLong != pHeadShort){
pHeadLong = pHeadLong->next;
pHeadShort = pHeadShort->next;
}
return pHeadLong;
}
private:
// 获得链表长度
unsigned int GetListLength(ListNode* pHead){
if(pHead == NULL){
return 0;
}
unsigned int length = 1;
while(pHead->next != NULL){
pHead = pHead->next;
length++;
}
return length;
}
};
python思路2:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
if(pHead1==None and pHead2==None):
return None
p1=pHead1
p2=pHead2
while p1!=p2:
p1=p1.next if p1!=None else pHead2
p2=p2.next if p2!=None else pHead1
return p1