首页 > 其他分享 >环状替换法详解

环状替换法详解

时间:2023-05-16 12:33:21浏览次数:41  
标签:frac gcd temp nums int 替换法 整数 详解 环状

环状替换法详解

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

链接:https://leetcode.cn/problems/rotate-array

示例:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

1.在官方解答中给出了环装替换法,不易理解,现给出推导:

⭐ 该方法实质可以理解为:

一个圆形桌子上吃饭,每个人想吃的菜不同,就移一下位置。(假设桌子不能转哈

一共有n个人,要往自己的左手边移动k个位置坐。

ex1:

对于其中一个元素 x ,间隔k回到自己要走a圈,a为整数;

要么一圈经过个元素呢? n/k个,对吧.(在这个n/k不一定是整数,但是实际要数那么个数就是向下取整

例如图1:从0开始,间隔3经过了 3和6 。个数为7/3,取整为2

假设x回到自己身上一共经过b个元素,b也是整数。

那么

\[a*\frac{n}{k} = b \]

注意:a是整数,b也是整数.

但是!注意了轰!n/k不一定是整数.

\[a*\frac{n}{k} 是整数,a又是最小的圈数,所以a=\frac{k}{gcd(k,n)} \]

\[为啥是\frac{k}{gcd(k,n)}呢?n=gcd(k,n)*m,k=gcd(k,n)*h \]

\[\frac{n}{k}也就是\frac{m}{h},m和h不可约,那么a=h=\frac{k}{gcd(k,n)}时最小 \]

所以:

\[遍历次数为:\frac{n}{b}=\frac{n}{a*\frac{n}{k}}=gcd(n,k) \]

所以遍历次数gcd(n,k)

2.C++代码如下
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if (k == 0)
            return;
        int N = nums.size();
        k = k % N;
        int j;
        int Num = gcd(N, k);
        for (int i = 0; i < Num; ++i)
        {
            j = i; //记录起点
            do
            {
                j = (j + k) % N;
                Swap(nums[i], nums[j]);
            } while (j !=i ); //判断有没有回到原来的位置
        }
       
    }
    void Swap(int& x, int& y)
    {
        int temp = x;
        x = y;
        y = temp;
    }
    //求最大公约数
    int gcd(int a, int b)
    {
        int temp;
        if (a < b)
            Swap(a, b);
        while (b>0)
        {
            temp = a % b;
            a = b;
            b = temp;
        }
        return a;
    }
};

比如图1:0-3-6-2-5-1-4-0

其实就是每次进行交换,0号说我要坐3号位置,那么3号说我让给你你吧,我先坐0号。

但是3号自己也要动,所以3号又从0号坐到了6号

标签:frac,gcd,temp,nums,int,替换法,整数,详解,环状
From: https://www.cnblogs.com/Kellen-Gram/p/17404563.html

相关文章

  • Vue跨域详解
    碰到这种问题,其实你的接口已经通了,但是在页面上就是访问不通过。你可以把API请求地址单独拎出来新开个网站打开看请求是否成功,成功,但是你的项目不通。有那么几个可能吧:1、请求头设置错误headers={ 'Content-Type':'application/json'//错误的'......
  • Android AlertDialog 详解
    创建对话框一个对话框一般是一个出现在当前Activity之上的一个小窗口.处于下面的Activity失去焦点,对话框接受所有的用户交互.对话框一般用于提示信息和与当前应用程序直接相关的小功能.AndroidAPI支持下列类型的对话框对象:警告对话框AlertDialog: 一个可以有......
  • MATLAB快速傅里叶变换(fft)函数详解
    MATLAB快速傅里叶变换(fft)函数详解调用:​​1.Y=fft(y);Y=fft(y,N);式中,y是序列,Y是序列的快速傅里叶变换。y可以是一向量或矩阵,若y为向量,则Y是y的FFT,并且与y具有相同的长度。若y为一矩阵,则Y是对矩阵的每一列向量进行FFT。说明:函数fft返回值的数据结构具有对称性根据采样定......
  • Docker详解
    什么是docker?Docker是一个应用打包、分发、部署的工具你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。打包:就是把你软件运行所需的依赖,第三方库,软件打包打包在一起......
  • Explain执行计划key_len详解
    我们在使用Explain查看SQL执行计划时,其中有一列为key_kenEXPLAINselect*FROMuserWHEREid=1;key_len表示使用的索引长度,key_len可以衡量索引的好坏,key_len越小索引效果越好,那么key_len的长度是如何计算的?常见的列类型长度计算:CREATETABLE`user`(`id`bigint......
  • MYSQL数据库之事务隔离级别详解
    本系列为:MySQL数据库详解,为千锋资深教学老师独家创作致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【关注】持续追更~文末有本文重点总结,技术类问题,也欢迎大家和我们沟通交流!前言从今天开始本系列内容就带各位小伙伴学习......
  • Shell中的if语法详解
    if语法if[condition1];thencommand1elif[condition2];thencommand2elsecommand3fiif判断条件文件/目录判断常用判断[-aFILE]如果FILE存在则为真。[-dFILE]如果FILE存在且是一个目录则返回为真。[-eFILE]如果指定的文件或目录存......
  • pom.xml详解
    <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">&......
  • Go语言中List 基本用法与源码详解
    Go-list在Go语言的标准库中,提供了一个container包,这个包中提供了三种数据类型,就是heap,list和ring,本节要讲的是list的使用以及源码剖析。要使用Go提供的list链表,则首先需要导入list包,如下所示:packagemainimport("container/list")导入包之后,需要了解list中定义了两种数据......
  • ECMAScript6新特性【函数的扩展(函数参数的默认值、箭头函数、rest 参数、name 属性)
    ......