链表反转+链表环起点

递归反转链表

/*反转链表的前N个节点*/
class Solution3_N {
	ListNode* pHead; //假设有个头结点
	ListNode* successor = pHead->next; //后驱节点
	ListNode* reverseN(ListNode* pHead, int n) {
		//反转以head为起点的前N个节点,返回:新的头结点
		if (n == 1) { //递归的出口条件
			//记录第n+1个节点
			successor = pHead->next; 
			return pHead;
		}
		//以pHead为起点,反转前n-1个节点
		ListNode* last = reverseN(pHead->next, n - 1); //pHead临时节点下移一个
		pHead->next->next = pHead;
		//反转后的head节点和后面的节点连接起来f
		pHead->next = successor;
		return last;
	}
};
123456
假设R( Node(1), 3 ),反转前3个
结果:
  123456
第一步:  R( node(1) -->next, 3-1)  =====>R( node(2), 2 )
第二步: R(node(2)--->next,  2-1======>R( node(3),1 )
               if(n==1)为真
                  successor =  node(3)-->next ;    ======> successor = node(4)
                  return node(3); //退出递归
 返回第一步:
                 last = node(3);        //last指向node 3, successor指向node 4
                 pHead->1 -> 23 ← last   45
                 pHead不变, 仍然指向node 1
                 pHead->next 仍然指向 node 2 ;
                 pHead->next->next = pHead;    使得2指向1
     			                   pHead->123 ← last     successor --> 45
     			                   pHead->next = node(4) successor          ;// 1下一个节点指向4
     
[链表环](https://mp.weixin.qq.com/s/dVqXEMKZ6_tuB7J-leLmtg)
/*判断链表是否有环*/
bool hasCycle(ListNode *head) {
	//快慢指针初始化指向head
	ListNode* slow = head;
	ListNode* fast = head;
	//快指针走到末尾时候停下来
	while (fast->next !=nullptr &&fast!=nullptr)
	{
		slow = slow->next;
		fast = fast->next->next; 
		if (slow == fast) {
			return true;
		}
	}
	return false;
}
/*链表环的起点*/
ListNode* detectCycle(ListNode*head) {
	ListNode* fast;
	ListNode* slow;
	fast = slow = head;
	while (fast!=nullptr&& fast->next!=nullptr)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow) break; 
		/*存在环则退出循环进行下一步操作
		  并且fast针和slow相交
		  fast比slow多走的路程就是他在环中绕圈

		*/
	}
	if (fast == nullptr || fast->next == nullptr) {
		//快指针遇到空指针说明没有环
		return NULL;
	}
	// 重新指向头结点
	slow = head;
	while (slow!=fast)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}

一定是快的追慢的,快的比慢的多走了A步,并且, 如果fast走不到1圈,是追不上慢的!而且是正好走一圈就遇到了slow,如果fast走一圈多铁定是遇到并且超过slow的了。
那就是说如果走一圈,A就是环的长度
m:表示从head到环起点
x表示从环起点到第一次相遇点的 距离

slow:  m+x = k    ===>    k-x = m 
fast:   m+x+A = 2k
===> A = K; 环长度等于slow走过的路
那么从相遇点再走多少能到达环起点?当然是 环长-x
===>  A - X = M
那就是说从相遇点再走m步到达起点!
那这样从相遇点开始规定 fast和slow的速度一致,
slow再次从head出发,
  再走m步就遇到从相遇点出发的fast。
  此时返回slow或者fast就行了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值