题目
给定一个数组,将数组中的元素向右移动 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]
思路
首先看到这道题目,我的第一反应就是找到一个分界点,在这个数组中的前半部分元素可以右移,并且下标只要直接加上移动的范围。
如图,在数组下标4的时候,还是只需要对下标直接加上移动范围就可以满足移动数组,但是如果再大的话,就不可以进行直接移动。
因此我们可以换一种思路,因为我们知道下标为5的时候移动到新数组的第一位。
简单来说,就是我们找到这个分界点5,就可以将5后面的元素全部插到新数组的开始,并且将0-4的下标元素插到5、6、7下标之后,就可以了
插好之后新数组的下标如图所示,因此我们就可以解决这道题了。
代码
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (k < 0)
return ;
//如果移动步数大于size的话,实际上就是超过了一个周期,没必要移动那么多次
if (k > nums.size())
k = k % nums.size();
//一个新数组
int* arr = new int[nums.size()];
int j = 0;
int i;
for (i = 0;i<nums.size();i++)
{
//这里就是找到需要移动到数组最前面的数字
if ((i + k) >= nums.size())
{
arr[j] = nums.at(i);
j++;
}
}
for (i = 0; i < (nums.size() - k); i++)
{
//这里就是将原数组的开头插到新数组后面去
arr[j] = nums.at(i);
j++;
}
for (i = 0; i < nums.size(); i++)
{
nums.at(i) = arr[i];
}
for (i = 0; i < nums.size(); i++)
{
cout << nums.at(i) << endl;
}
}
};
注意
这题需要先理清一下思路,如果一直想着先去移动前面的数字,我认为似乎没那么容易想出来,我就想能不能先提取后面的,感觉这个办法还可以。