有环链表的环起点

用两个指针,一个快指针一次走两步,一个慢指针一次走一步。快慢指针可以重合表示链表有环,此时距离环起点的距离和起点距离环起点的距离相等。

#include "bits/stdc++.h"
using namespace std;
struct List {
    List* next;
};
List* beginOfCircle(List* p1, List* p2) {
    while (p1 != p2) {
        p1 = p1->next;
        p2 = p2->next;
    }
    return p1;
}
List* hasCircle(List* head) {
    List* fast = head;
    List* slow = head;
    while (slow != NULL && fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) {
            return beginOfCircle(head, slow);
        }
    }
    return NULL;
}
List* init() {
    List* rec = (List*)malloc(sizeof(List));
    rec->next = NULL;
}
int main() {
    List* head;
    List* ans;
    List* now;
    List* res;
    /*
    head = (List*)malloc(sizeof(List));
    head->next = (List*)malloc(sizeof(List));
    head->next->next = (List*)malloc(sizeof(List));;
    head->next->next->next = (List*)malloc(sizeof(List));
    head->next->next->next = head->next;
    res = hasCircle(head);
    if (res == head->next) {
        puts("YES");
    } else {
        puts("NO");
    }
    */
    int n, m;
    scanf("%d %d", &n, &m);
    head = init();
    now = head;
    while (--n) {
        now->next = init();
        now = now->next;
    }
    ans = now;
    if (m == 0) {
        res = hasCircle(head);
        if (res == ans) {
            puts("YES");
        } else {
            puts("NO");
        }
        return 0;
    }
    while (--m) {
        now->next = init();
        now = now->next;
    }
    now->next = ans;
    res = hasCircle(head);
    if (res == ans) {
        puts("YES");
    } else {
        puts("NO");
    }
    return 0;
}

main函数里为验证,可以输入环起点的编号n和一个环的长度m。最后返回的结果等于环起点输出“YES”,当链表中无环的情况下返回NULL输出结果为“NO”;

转载于:https://www.cnblogs.com/Angel-Demon/p/10199477.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
约瑟夫(Josephus Problem)是一个经典的计算机科学问题,常被用来展示递归和循的概念,但通常不会直接用面向对象链表的方式实现。然而,我们可以设计一个类结构来模拟这个问题,虽然不是典型的链表操作,但它展示了如何使用对象和类来模拟状数组。 在面向对象的约瑟夫实现中,我们可以创建一个`Node`类代表中的元素,每个节点包含一个值和一个指向下一个节点的引用。然后,我们可以有一个`JosephusRing`类,它维护一个节点列表并实现一个`getNextKthNode`方法,该方法根据给定的步长k找到下一个需要删除的节点。 这是一个简化版本的实现示例: ```python class Node: def __init__(self, value, next_node=None): self.value = value self.next_node = next_node class JosephusRing: def __init__(self, values, k): self.head = Node(values) for i in range(1, len(values)): self.head.next_node = Node(values[i], self.head.next_node) self.head.next_node.next_node = self.head # 创建 self.k = k def getNextKthNode(self): current = self.head for _ in range(self.k - 1): # 跳过前k-1个节点 current = current.next_node while True: current = current.next_node if current == self.head: # 当回到起点时,找到了新的起始点 break return current # 示例 ring = JosephusRing([1, 2, 3, 4, 5], 3) # 步长k为3 result = ring.getNextKthNode() ``` 相关问题: 1. 在这个实现中,`JosephusRing`类的主要作用是什么? 2. `getNextKthNode`方法是如何找到下一位被淘汰的节点的? 3. 如果改变步长k,这个的淘汰顺序会发生什么变化?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值