当前位置:首页 » 《资源分享》 » 正文

【算法训练营】(day5)_flyyyya的博客

13 人参与  2021年10月13日 10:43  分类 : 《资源分享》  评论

点击全文阅读


算法训练营

    • 环形链表
    • 环形链表Ⅱ
    • 复制带随机指针的链表

环形链表

在这里插入图片描述
解题思路:
这道题我们使用快慢指针的方法,如果有节点,快指针走到会回头于慢指针汇合,根据这个思想我们解答一下这个题目。

bool hasCycle(struct ListNode *head) {
	if (head == NULL || head->next == NULL)
	{
		return false;
	}
	ListNode* slow = head;
	ListNode* fast = head->next;
	while (slow!=fast)
	{
		if (fast == NULL || fast->next == NULL)
			return false;
		slow = slow->next;
		fast = fast->next->next;
	}
	return true;
}

环形链表Ⅱ

在这里插入图片描述
解题思路:
假设链表环前有 aa 个节点,环内有 bb 个节点
本题核心思路:走 a+nba+nb 步一定处于环的入口位置

利用快慢指针 fast 和 slow,fast 一次走两步,slow 一次走一步
当两个指针第一次相遇时,假设 slow走了 ss 步,下面计算 fast 走过的步数
i. fast 比 slow 多走了 nn 个环:f = s + nbf=s+nb
ii. fast 比 slow 多走一倍的步数:f = 2sf=2s --> 跟上式联立可得 s = nbs=nb
iii. 综上计算得,f = 2nbf=2nb,s = nbs=nb
也就是两个指针第一次相遇时,都走过了环的倍数,那么再走 aa 步就可以到达环的入口
让 fast 从头再走,slow 留在原地,fast 和 slow均一次走一步,当两个指针第二次相遇时,fast 走了 aa 步,slow 走了 a+nba+nb 步
此时 slow 就在环的入口处,返回 slow

struct ListNode *detectCycle(struct ListNode *head) {
	if (head == NULL || head->next == NULL)
	{
		return false;
	}
	ListNode* slow = head;
	ListNode* fast = head->next;
	while (fast != NULL)
	{
		slow = slow->next;
		if (fast->next == NULL)
		{
			return NULL;
		}
		fast = fast->next->next;
		if (fast == slow)
		{
			ListNode* ptr = head;
			while (ptr != slow)
			{
				ptr = ptr->next;
				slow = slow->next;
			}
			return ptr;
		}
		return NULL;
	}

复制带随机指针的链表

在这里插入图片描述
解题思路:
我们首先将该链表中每一个节点拆分为两个相连的节点这样,我们可以直接找到每一个拷贝节点 的随机指针应当指向的节点,即为其原节点的随机指针指向的节点 的后继节点需要注意原节点的随机指针可能为空,我们需要特别判断这种情况。
当我们完成了拷贝节点的随机指针的赋值,我们只需要将这个链表按照原节点与拷贝节点的种类进行拆分即可,只需要遍历一次。同样需要注意最后一个拷贝节点的后继节点为空,我们需要特别判断这种情况。

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if (head == nullptr) {
            return nullptr;
        }
        for (Node* node = head; node != nullptr; node = node->next->next) {
            Node* nodeNew = new Node(node->val);
            nodeNew->next = node->next;
            node->next = nodeNew;
        }
        for (Node* node = head; node != nullptr; node = node->next->next) {
            Node* nodeNew = node->next;
            nodeNew->random = (node->random != nullptr) ? node->random->next : nullptr;
        }
        Node* headNew = head->next;
        for (Node* node = head; node != nullptr; node = node->next) {
            Node* nodeNew = node->next;
            node->next = node->next->next;
            nodeNew->next = (nodeNew->next != nullptr) ? nodeNew->next->next : nullptr;
        }
        return headNew;
    }
};


点击全文阅读


本文链接:http://zhangshiyu.com/post/29846.html

节点  指针  链表  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1