天天看点

leetcode刷题笔记189

写在前边

很简单的一道题目,我怀疑我们期末考试就会考这样的题目,刚巧拿这个练练手。

题目

给定一个数组,将数组中的元素向右移动 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]

示例 2:

输入: [-1,-100,3,99] 和 k = 2

输出: [3,99,-1,-100]

解释:

向右旋转 1 步: [99,-1,-100,3]

向右旋转 2 步: [3,99,-1,-100]

说明:

尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。

要求使用空间复杂度为 O(1) 的 原地 算法。

难就难在需要O(1)的空间复杂度,刚开始做会觉得有点棘手,但是知道怎么做之后,会觉得特别巧妙,本质还是用数学的思想。

设有一个字符串ABCDEFG

易知,将该字符串完全倒序,会得到GFEDCBA,而如果将前四个倒序,是DCBAEFG,可以看到,这里实现了局部的倒序,如果再将整个字符串倒序呢?会得到GFEABCD,会发现,ABCD的顺序没有发生变化,只是往后移动了几位,而如果将前后分别倒序,再整个倒序的话,可以很轻松的得到我们要的结果,如:将前四位,后四位分别倒序,得到DCBAGFE,再将整个倒序,得到EFGABCD,与将ABCDEFG按照题目的方式进行移动得到的结果一模一样!

按照这样的的思想,我们很容易就能解出来这道题。交答案的时候WA了一次,是因为没有考虑到移动位数大于整个数组的长度,这个时候需要取模。

源码如下:

#include"iostream"
#include"algorithm"
#include"vector"
using namespace std;
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        vector<int>::iterator it;
        it=nums.begin();
        if(nums.size()>1)
        {
            if(nums.size()-k<0);
            {
                k=k%nums.size();
            }
            it=it+nums.size()-k;
            reverse(nums.begin(),it);

            reverse(it,nums.end());

            reverse(nums.begin(),nums.end());
        }
    }
};
int main()
{
    vector<int> temp={-1,-100,3,99};
    Solution s;
    s.rotate(temp,100);
    for(int i=0;i<temp.size();i++)
    {
        cout<<temp[i]<<endl;
    }
    system("pause");
    return 0;
}
           

记得学会使用stl,像这里直接用reverse(),很方便。