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用来寻找当前元素的移动后落脚点
}
}
leetcode初级———旋转数组的多种算法总结相关推荐
- LeetCode 初级 - 旋转数组
旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向 ...
- 刷爆LeetCode之旋转数组
旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7]和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右 ...
- LeetCode 189. 旋转数组(环形替换)
1. 题目 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1:输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向 ...
- Leetcode 189. 旋转数组 (每日一题 20210909)
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数.进阶:尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问 ...
- leetcode(189) 旋转数组
**给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 进阶: 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 算法解 ...
- Leetcode 189. 旋转数组 解题思路及C++实现
方法一:暴力方法 解题思路: 用栈存储后面的 k 个元素,然后将 nums 数组的元素往后挪 k 位,然后再将栈中的元素存进nums数组中. class Solution { public:void ...
- leetcode练习旋转数组
第一中方法即为hash的方法: 第二种采用了循环,但是不全面,输入测试用例为[1,3], k=3 时,无法进行交换: class Solution { public:void rotate(vecto ...
- leetcode 189. 旋转数组
题目 思路 先左边翻转,再右边翻转,最后整体翻转. 注意存在翻转超过一个周期的情况,要先取余,避免越界. 题解 class Solution {public void rotate(int[] num ...
- LeetCode 1238. 循环码排列(格雷编码+旋转数组)
1. 题目 给你两个整数 n 和 start.你的任务是返回任意 (0,1,2,,...,2^n-1) 的排列 p,并且满足: p[0] = start p[i] 和 p[i+1] 的二进制表示形式只 ...
最新文章
- Flutter开发之HTTP网络请求:dio库(28)
- spring的log4j listener(webAppRootKey)
- mysql死锁分析_MySQL死锁分析
- Postgresql kill用户进程
- 字段类型 mysql_mysql 常用字段类型
- swift Tablview中cell 的用withtag方法绑定里面的button
- python避障小车_基于深度学习的自动避障小车_7_代码说明
- 后台管理软件测试用例,如何进行测试用例管理?
- 支付宝小程序获取用户手机号php,小程序登录、获取用户信息、手机号
- unctf2020部分wp
- nim game代码java_LeetCode Nim Game
- U盘无法格式化(提示U盘文件系统变为了RAW格式)【一般应用】
- 基于Android的校园跳蚤市场(二手)的设计与实现(新版)
- CentOS 中安装nginx
- 海外区块链投融资持续火热 | 产业区块链发展周报
- 使用 HBuilderX 打包IOS 和 安卓
- 上升了百分之几怎么算_上涨百分之多少怎么算
- 汇编语言中word ptr | byte ptr分别是什么意思
- nginx配置https证书
- 智能手机巨头Oppo加快AR的发展
热门文章
- kali Linux单用户模式的退出方法
- 字模在c语言运行后出现乱码,C语言字模问题
- 计算机汉字字模信息怎么算,汉字字模库字模.PPT
- http请求报文头部vary信息
- 阿里云部署hexo博客之旅
- Android签名aab文件
- 索引一般加在什么字段上_在价值上亿的豪华游轮做服务员,是什么体验?网友:也就一般般吧...
- css3实现磨砂效果,CSS3打造磨砂玻璃背景效果
- 「残酷乐队生涯」信息参考
- 为什么我魅族m2显示无服务器,魅族m2升级刷机flyme4.0教程及注意事项.doc