【每日一题】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)的原地算法

题解

🙋‍♂️今日打卡~~

思路

拿到这道题,第一看过去,第一个想法是使用额外的空间,新申请一个一维数组用于保存当前需要移动的后半段元素,等待前半段元素在原始数组中移动到相应的位置之后,再把新数组的后半段元素移动到原数组的前半段。

题目下面的说明说是要求使用原地算法,就是不使用额外的空间。那就需要在原数组上下功夫,怎么才能让后半段元素变到前半段,前半段的元素变到后半段,确实需要想一想。想了一会,终于想通了,我们可以先把整个数组翻转,这样后半段元素已经变到前面了,只是后半段元素的位置是反的,还需要将翻转后的数组按照[0,k]和[k+1,n]翻转一次,这样就可以得到结果。

步骤

第一步,[0,n-1]数组长度整体翻转

第二步,[0,k-1]长度翻转

第三步,[k,n-1]长度翻转

注意

  • K需要对数组长度进行取余,可以减少不必要的操作。

代码

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k%=n;
        if(k==0){
            return;
        }
        reverse(nums,0,n-1);
        reverse(nums,0,k-1);
        reverse(nums,k,n-1);
    }
    private void reverse(int[] nums,int l,int r){
        while(l<r){
            int tmp = nums[l];
            nums[l] = nums[r];
            nums[r] = tmp;
            l++;
            r--;
        }
    }
}

总结

面对数组类型的题目,其实简单方法大部分人都可以想出来,只不过会有高时间复杂度,或者高空间复杂度,如果要优化,就需要认真思考。但是如果没有想出来最优解也不要太难受,因为有些东西是需要学习的,或者换句话说,需要看别人的题解,就好像是知识一样,没学过,不了解,很正常,我们只有见多了,看多了,把看过的吸收成自己的,这样才能提升自己。有做不错来的题,去把题解吃透吧。

写在后面

今天在疯狂循环播放《烟火里的尘埃》,不知道为什么我听这首歌的时候,并不会感觉到悲伤,而是感觉到一种气势磅礴,网抑云时间到了,“笑的开怀,哭的坦率,为何表情要让这世界安排”。还有就是最后那假音高音感觉确实像是腾空的烟火🎆,到最高点炸开。其实我之前是没有怎么听过他的歌的,只知道他是快乐男声出来的,纯路人,听完这首歌之后,感觉他还是很有能力的,小伙伴们可以去听听。

各位客官,走过路过,点个赞再走吧,感谢🙏
关注即可提高学习效率,关注不迷路

全部评论

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
牛客279957775号:铁暗恋
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务