IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode初级———旋转数组的多种算法总结 -> 正文阅读

[数据结构与算法]leetcode初级———旋转数组的多种算法总结

题目描述:

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

(来源:leetcode)

1.数组拆分

//经观察发现:将数组元素全部后移k单位即将后 k%length 个元素前置,为此我们可以借助一个新数组存储这些 需要前置的元素,然后整体迁移。

void rotate(int* nums, int numsSize, int k){
? ? k = k % numsSize;
? ? if(!nums || numsSize < 2 || k <= 0) return;
? ? int maxInd = numsSize - 1;
? ? int oriInd = maxInd - k;
? ? int opInd = oriInd + 1;
? ? int i, j = 0;
? ? int temp[k];
? ? for(i = 0;i < k; i++){
? ? ? ? temp[i] = nums[opInd++];
? ? } //存储需要前置的元素
? ? for(i = oriInd; i >= 0; i--){
? ? ? ? nums[maxInd--] = nums[i];
? ? } //剩余元素后置
? ? for(i = 0; i < k; i++){
? ? ? ? nums[i] = temp[i];
? ? } //元素前置
}

2.暴力解法

//新创建一个数组,按原数组旋转后的正确顺序到新数组中,再放回。

void rotate(int* nums, int numsSize, int k){
? ? if(!nums || numsSize == 0 || k == 0) return;
? ? int i, temp[numsSize];
? ? for(i = 0; i < numsSize; i++){
? ? ? ? temp[(i+k)%numsSize] = nums[i];
? ? } //在新数组的元素移动后位置摆放各个元素
? ? for(i = 0; i < numsSize; i++){
? ? ? ? nums[i] = temp[i];
? ? } //拷贝回原数组
}

3.三次原地反转

//思路同一,需要把后 K 个元素前置,可以先将整个数组翻转,再把前 k 个元素翻转,最后剩余元素翻转。这种方法空间复杂度低。

void rotate(int* nums, int numsSize, int k){
? ? if(!nums || numsSize < 2 || k == 0) return;
? ? k = k % numsSize;
? ? int i;
? ? for(i = 0; i < numsSize / 2; i++){
? ? ? ? nums[i] = nums[i] + nums[numsSize-i-1];
? ? ? ? nums[numsSize-i-1] = nums[i] - nums[numsSize-i-1];
? ? ? ? nums[i] = nums[i] - nums[numsSize-i-1];
? ? } // 整个数组翻转
? ? for(i = 0; i < k / 2; i++){
? ? ? ? nums[i] = nums[i] + nums[k-i-1];
? ? ? ? nums[k-i-1] = nums[i] - nums[k-i-1];
? ? ? ? nums[i] = nums[i] - nums[k-i-1];
? ? } // 前 k 个元素翻转
? ? for(i = k; i < (numsSize + k) / 2; i++){
? ? ? ? nums[i] = nums[i] + nums[numsSize-1-i+k];
? ? ? ? nums[numsSize-1-i+k] = nums[i] - nums[numsSize-1-i+k];
? ? ? ? nums[i] = nums[i] - nums[numsSize-1-i+k];
? ? } // 剩余元素翻转
}

4.临时变量

// 借助一个临时变量持续元素向后迁移。但需要注意当 length%k = 0 时,这一特殊条件。

void rotate(int* nums, int numsSize, int k){
? ? if(!nums || numsSize < 2 || k == 0) return;
? ? k = k % numsSize;
? ? int temp = nums[0], i = 0, j = k, t, count = 0;?
? ? while(i++ < numsSize){ //持续对每一个元素都摆放到正确位置
? ? ? ? t = nums[j];
? ? ? ? nums[j] = temp;
? ? ? ? temp = t;
? ? ? ? if(j == count){ //当 j 又回到出发点时说明发生了原地打转
? ? ? ? ? ? count = (count + 1) % numsSize; //从下一个开始
? ? ? ? ? ? j = count;
? ? ? ? ? ? temp = nums[j];
? ? ? ? }
? ? ? ? j = (j + k) % numsSize; //j用来寻找当前元素的移动后落脚点
? ? }
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:36:44  更:2022-09-04 01:39:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 18:11:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码