算法训练营(day5)
Posted flyyyya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法训练营(day5)相关的知识,希望对你有一定的参考价值。
算法训练营
环形链表
解题思路:
这道题我们使用快慢指针的方法,如果有节点,快指针走到会回头于慢指针汇合,根据这个思想我们解答一下这个题目。
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;
}
};
以上是关于算法训练营(day5)的主要内容,如果未能解决你的问题,请参考以下文章