约瑟夫环的三种解法(循环链表、数组和用数组模拟链表)

news/2024/11/23 2:19:04/

目录

前言

一、用循环链表实现

二、用数组实现

三、用数组模拟链表实现



前言

题目描述

编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。

下一个人继续从 1 开始报数。

n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?

数据范围:​

进阶:空间复杂度 O(1),时间复杂度 O(n)

示例 1

输入:5,2    

返回值:3    

说明:

开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开

1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开

1,3,5,从5开始报数,5->1,1->2编号为1的人离开

3,5,从3开始报数,3->1,5->2编号为5的人离开

最后留下人的编号是3      

示例 2

输入:1,1

返回值:1

一、用循环链表实现

typedef struct Node
{int id;  // 编号(从 1 开始)struct Node* next;
}Node;int ysf(int n, int m) 
{// 采用尾插法构造编号为 1 ~ n 的循环链表Node* phead = (Node*)malloc(sizeof(Node));  // 头指针phead->id = 1;Node* tail = phead;  // 尾指针for (int i = 2; i <= n; ++i){Node* newnode = (Node*)malloc(sizeof(Node));newnode->id = i;newnode->next = NULL;tail->next = newnode;tail = newnode;}tail->next = phead;  // 让最后一个节点的 next 域指向第一个节点// 开始Node* cur = phead;Node* prev = tail;int count = 1;  // 计数器while (cur != prev){if (count == m){prev->next = cur->next;free(cur);cur = prev->next;count = 1;  // 重置为 1}else {prev = cur;cur = cur->next;++count;}}int ret = cur->id;free(cur);return ret;
}

 

二、用数组实现

int ysf(int n, int m)
{int* is_out = (int*)calloc(n, sizeof(int));  // 0 表示在圈内,1 则表示退出int number = n;int count = 1;  // 计数器int i = 0;while (number > 1){if (is_out[i] == 0)  // 圈内的人报数{if (count == m){is_out[i] = 1;  // 退出--number;count = 1;  // 重置为 1}else{++count;}}// 法一:++i;if (i >= n){i = 0;}// 法二:// i = (i + 1) % n;}for (i = 0; i < n; ++i){if (is_out[i] == 0){break;}}free(is_out);  // 释放动态开辟的内存空间return i + 1;  // 返回编号
}

 

三、用数组模拟链表实现

int ysf(int n, int m)
{int* next = (int*)calloc(n, sizeof(int));for (int i = 0; i < n - 1; ++i){next[i] = i + 1;}// next[n - 1] == 0int cur = 0;int prev = n - 1;int count = 1;  // 计数器while (cur != prev){if (count == m){next[prev] = next[cur];next[cur] = -1;  // 退出cur = next[prev];count = 1;  // 重置为 1}else{prev = cur;cur = next[cur];++count;}}free(next);  // 释放动态开辟的内存空间return cur + 1;  // 返回编号
}

创作不易,可以点点赞,如果能关注一下博主就更好了~ 


http://www.ppmy.cn/news/51373.html

相关文章

线程同步方式之一互斥锁

线程同步的4种方式&#xff1a;互斥锁、条件变量、读写锁、信号量 了解概念-临界资源、互斥、临界区、原子性 回想一下在信号量那部分提起过的几个概念&#xff0c;将多个执行流串行安全访问的共享资源称为临界资源&#xff0c;多个执行流中访问临界资源的代码所在的地址空间…

五一假期出游攻略【诗与远方】

原文在&#xff1a;PUSDN 可以导入作为模板引用。 五一旅行计划 假期倒计时 [该类型的内容暂不支持下载] 本次目标&#xff1a;五一旅行计划【画饼版】 前言 任何一个地方&#xff0c;一个城市&#xff0c;都有可观赏的地方&#xff0c;如果没去过邢台的&#xff0c;建议五一去…

数组的知识点

数组 1、概念2、二分查找 主要理解区间定义&#xff0c;对循环条件的影响3、移除元素有序数组的平方长度最小的子数组&#xff08;滑动窗口&#xff09;螺旋矩阵总结 1、概念 数组是存放在连续空间上的相同类型的数据集合。 特点&#xff1a; 1、数组下标都是从0开始的&#x…

QT笔记——QtPropertyBrowser的使用

上一节&#xff0c;我们将了如何去配置QtPropertyBrowser 本节&#xff0c;我们将说明 如何 去 使用QtPropertyBrowser 这个属性类的一些基本知识 简单的几种用法&#xff1a; 首先&#xff1a; 我们需要创建一个Widget 提升一个类 为 QtTreePropertyBrowser .h文件 QtVariant…

springboot,Flowable 流程实例的激活与挂起(二)

一.简介 接上一篇 springboot&#xff0c;Flowable 流程实例的激活与挂起&#xff08;一&#xff09; 二.流程实例的挂起与激活 1.流程实例的挂起 挂起一个流程实例的代码如下&#xff1a; Test void test08() {List<ProcessDefinition> list repositoryService.cr…

安全测试:配置管理潜在威胁

一、配置管理威胁有哪些 明文信息传输漏洞敏感信息泄露默认或可猜解用户账户会话重放攻击测试验证码缺陷http方法测试 二、明文信息传输和存储漏洞 漏洞描述&#xff1a; 页面中没有对传输的用户名和密码等敏感信息进行加密后传输。用户密码后台存储是否加密。 产生原因&a…

手写axios源码系列二:创建axios函数对象

文章目录 一、模块化目录介绍二、创建 axios 函数对象1、创建 axios.js 文件2、创建 defaults.js 文件3、创建 _Axios.js 文件4、总结 当前篇章正式进入手写 axios 源码系列&#xff0c;我们要真枪实弹的开始写代码了。 因为 axios 源码的代码量比较庞大&#xff0c;所以我们这…

mall-swarm微服务商城系统

mall-swarm是一套微服务商城系统&#xff0c;采用了 Spring Cloud 2021 & Alibaba、Spring Boot 2.7、Oauth2、MyBatis、Docker、Elasticsearch、Kubernetes等核心技术&#xff0c;同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心…