LeetCode之反转数组

这篇博客讨论了LeetCode中的反转数组问题,解释了如何在O(1)额外空间内将数组旋转k步。文章指出,数组反转不等于数组倒序,并提供了三种不同的解题方法,包括超时的直接交换元素法以及利用k%n优化的高效Java和C++方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode之反转数组

Question:
Rotate Array QuestionEditorial Solution My Submissions
Total Accepted: 97790
Total Submissions: 425073
Difficulty: Easy
Contributors: Admin
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Could you do it in-place with O(1) extra space?。在O(1)的空间内完成,也就不能用一个辅助数组了。

题意:给你一个数组,然后n是数组的元素个数,k是步骤,然后把数组反转。
我一开始对数组反转不太理解,因为以前没有碰到过(高手请忽略)。我一开始以为是数组反转是不是把数组倒序输出就行了。比如1,2,3,4 ===>4,3,2,1 ;一些语言的提供的函数也确实是这样,比如Java的Collections类下的reverse函数就是用于反转的。详情请见:http://www.runoob.com/java/arrays-reverse.html。因此,在这里应该区别,反转不是倒序输出,虽然输出的形式可能是一样,但是反转后,数组的元素位置是会发生改变,虽然你使用倒序输出可能可以通过OJ。这里的k 个步骤,我不是很理解。如果你清楚,烦请告知下。那么看样例,这里的k=3,可以理解是把后面3个数组元素移动到前面去。就比如k = 4;那么输出应该是 [4,5,6,7,1,2,3]。

从图片中的个人测试样例,是这样的。

那么下面怎么解呢?先来看一种简单易懂的。

public class solution{
    public void rotate(int[] nums, int k){
        int temp;
        int n = nums.length;
        for(int step = 0; step < k; step++){
            temp = nums[n - 1];
            for(int i = n - 1; i > 0; i--){
                //后面的值覆盖前面的值
                nums[i] = nums[i-1];
            }
            //把最后面的值赋值给第一个元素。
            nums[0] = temp;
        }
    }
} 

上面的是Java的代码实现,比较容易理解,数组的变化如下:

[1,2,3,4,5,6,7]         //未做反转的数组
[7,1,2,3,4,5,6]         //step = 0时
[6,7,1,2,3,4,5]         //step = 1时
[5,6,7,1,2,3,4]         //step = 2时

可见,如此交换两个值,我们的确可以得到对应的结果。当这种解法面对数组大的时,超时了。因为每一个step,数组可能都需要做移动n-1位的赋值操作。数组的移动是很费时的。时间复杂度为O(step*n);
因此,我使用了下面两种做法。
Java 方案:

package rotateArray;

public class RotateArray {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int nums[] = {1,2,3,4,5,6,7};
        int k = 3;
        rotate(nums, k);
        for(int i = 0; i < nums.length; i++){
            System.out.print(nums[i]);
        }
    }

    public static void rotate(int[] nums, int k){
        //获取数组的长度
        int len = nums.length;
        k = k % len;
        //如果只有一个元素
        if(len == 1){
            return ;
        }
        /*如果k是0,那么k要是是0要么是length,但是这两种情况都不需要
         * 对数组做任何改变
        */
        if(k == 0){
            return ;
        }
        //反转K位之前的数组元素
        reverse(nums, 0, len-k-1);
        //反转K位之后的数组元素
        reverse(nums, len-k, len-1);
        //反转整个数组的元素
        reverse(nums, 0, len-1);
    }

    public static void reverse(int[] nums, int i, int j){
        int temp;     
        //对没有被操作的数组元素的最前面和最后面的进行交换达到反转效果
        while(i < j && i>=0){
            temp    = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            i++;      //左边向右移动一位
            j--;      //右边向左边移动一位
        }
    }
}

虽然说不能用辅助数组,但是C++使用vector容器装一个数组也能过。思考到k跟k%n的关系,这道题就变得很容易了。
C++方案:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        vector<int> t = nums;
        for(int i = 0; i < nums.size(); i++){
            nums[(i + k) % nums.size()] = t[i];
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值