LeetCode刷题(8)~旋转数组
【摘要】 题目描述
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [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]
123456...
题目描述
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [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
- 2
- 3
- 4
- 5
- 6
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
- 1
- 2
- 3
- 4
- 5
说明:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。
解答
提交代码_1(暴力解法)
void rotate(vector<int>& nums, int k) { int len=nums.size(); for(int i=0;i<k;++i) { int temp=nums[len-1]; for(int j=len-2;j>=0;--j) { nums[j+1]=nums[j]; } nums[0]=temp; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
运行结果(超时)
思路
每次移动一位,移动k位,则循环k次。
提交代码_2(反转数组)
class Solution {
public: void reverse(vector<int> &nums,int start,int end) { int count=(end-start+1)/2; int temp=0; for(int i=0;i<count;++i) { temp=nums[end]; nums[end]=nums[start]; nums[start]=temp; start++; end--; } } void rotate(vector<int>& nums, int k) { int len=nums.size(); k%=len; reverse(nums,0,len-1); reverse(nums,0,k-1); reverse(nums,k,len-1); }
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
运行结果
思路
首先对整个数组进行反转,然后对0~k-1前面的数组反转,再对后面的数组进行反转即可。【易错:当数组个数少于k时,这个比较坑,为了避免这个问题,对k进行重新赋值,k%=len】
提交代码_3【环状替换 难点】
void rotate(vector<int>& nums, int k) { int len=nums.size(); int count=0; for(int start=0;count<len;++start) { int current=start; int prv=nums[start]; do{ int next=(current+k)%len; int temp=nums[next]; nums[next]=prv; current=next; prv=temp; count++; }while (current!=start); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
运行结果
思路
传送门
C++完整测试代码
#include <iostream>
#include <vector>
using namespace std;
// 方法一:暴力解法
void rotate_1(vector<int> &nums, int k)
{
int len = nums.size();
for (int i = 0; i < k; ++i)
{ int temp = nums[len - 1]; for (int j = len - 2; j >= 0; --j) { nums[j + 1] = nums[j]; } nums[0] = temp;
}
}
// 方法二:反转数组
void reverse(vector<int> &nums, int start, int end)
{
int count = (end - start + 1) / 2;
int temp = 0;
for (int i = 0; i < count; ++i)
{ temp = nums[end]; nums[end] = nums[start]; nums[start] = temp; start++; end--;
}
}
void rotate_2(vector<int> &nums, int k)
{
int len = nums.size();
k %= len;
reverse(nums, 0, len - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, len - 1);
}
// 方法三:环转替换
void rotate_3(vector<int> &nums, int k)
{
int len = nums.size();
int count = 0;
for (int start = 0; count < len; ++start)
{ int current = start; int prv = nums[start]; do { int next = (current + k) % len; int temp = nums[next]; nums[next] = prv; current = next; prv = temp; count++; } while (current != start);
}
}
int main()
{
vector<int> a;
// 初始化 a=[1,2,3,4,5,6]
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);
a.push_back(6);
// 使用方法一
// rotate_1(a,3); // 使用方法二
// rotate_2(a,3); // 使用方法三
rotate_3(a, 3); // 打印结果
for (int i = 0; i < a.size(); ++i) cout << a[i] << " "; return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
题目来源
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-array
- 1
- 2
文章来源: haihong.blog.csdn.net,作者:海轰Pro,版权归原作者所有,如需转载,请联系作者。
原文链接:haihong.blog.csdn.net/article/details/107717058
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)