【判断单链表是否带环?求环的长度?环的入口点?以及每个算法的时间复杂度和空间复杂度】
【判断两个链表是否相交,求交点?(假设链表不带环)】
关于链表创建和基础的打印问题,在上一篇,戳链接 链表面试题(一)
13,【判断单链表是否带环?求环的长度?环的入口点?】
单链表带环问题,创建俩个指针,一个快指针,一个慢指针,快指针一下走两步,慢指针一下走一步,如果链表带环,最终两个指针会在环中相遇
//时间复杂度O(n),空间复杂度O(1)
SListNode* SListIsCycle(SListNode* list)//单链表带环问题
{
SListNode* pSlow = list;
SListNode* pQuick = list;
while (pQuick != NULL&&pQuick->_next != NULL)
{
pQuick = pQuick->_next->_next;//快指针一下走两步
pSlow = pSlow->_next;//慢指针一下走一步
if (pSlow == pQuick)//相遇
return pSlow;//后面算法中出现的meetNode就是这的pSlow相遇的指针
}
return NULL;
}
求环的长度问题,从环的相遇点或者环内的一个点开始,一个指针在这等着,另一个指针绕环走一圈,它的步数就是环的长度
////时间复杂度O(n),空间复杂度O(1)
int SListCycleLen(SListNode* meetNode)//求环的长度
{
SListNode* pCycle = meetNode;//等着的指针
SListNode* pNext = meetNode->_next;//计步的指针
int i = 1;
while (pNext != pCycle)//走到了开始的位置
{
pNext = pNext->_next;
i++;
}
return i;
}
求环入口点问题,在判断链表带环函数里,有一个相遇点(x),在遇到之前,慢指针走了(L+X),快指针走了(L+nC+X),但是快指针走的步数是慢指针的二倍,那么就能列出图上的算式,解出L=nC+X,那让一个指针从list走,一个从X位置走,他俩相遇的位置就是环的入口点了
//时间复杂度O(n),空间复杂度O(1)
int SListEntryNode(SListNode* list, SListNode* meetNode)//求环的入口点问题
{
SListNode* plist = list;//链表头结点
SListNode* pMeetNode = meetNode;//X位置的相遇点
int i = 1;
while (plist != pMeetNode)//相遇的位置就是环的入口点
{
plist = plist->_next;
pMeetNode = pMeetNode->_next;
i++;
}
return i;
}
14,【判断两个链表是否相交?求交点?(假设链表不带环)】
判断链表相交问题,先统计两个链表的长度,并判断两个链表的尾是不是一个尾,如果不是一个尾,那肯定没有相交,用长度大的减去长度小的,那么这时两个链表的长度都是一样的还相交,那么同时从俩链表表头开始往后走,遇到的内个结点就是相交点
int SListIsCrossNode(SListNode* list1, SListNode* list2)//判断链表相交(不带环)
{
if (list1 == NULL || list2 == NULL)
return NULL;
int len1 = 1;
SListNode* pTail1 = list1;
while (pTail1->_next != NULL)//统计链表1的长度
{
pTail1 = pTail1->_next;
len1++;
}
int len2 = 1;
SListNode* pTail2 = list2;
while (pTail2->_next != NULL)//统计链表2的长度
{
pTail2 = pTail2->_next;
len2++;
}
if (pTail1 != pTail2)//如果两个链表的尾巴不一样,那么肯定不相交
return -1;
SListNode* pNode1 = list1;
SListNode* pNode2 = list2;
int k;
if (len1 > len2)//让俩个指针从相同的位置出发
{
k = len1 - len2;
while (k--)
pNode1 = pNode1->_next;
}
else
{
int k = len2 - len1;
while (k--)
pNode2 = pNode2->_next;
}
k = 1;
while (pNode1 != pNode2)//相遇的点就是交点
{
pNode1 = pNode1->_next;
pNode2 = pNode2->_next;
k++;
}
return k;
}
如果有不对的地方,可以评论告诉我,望指导!
4544

被折叠的 条评论
为什么被折叠?



