使用Java解决数组旋转问题的方法详解

 更新时间:2026年03月20日 08:32:00   作者:牛肉胡辣汤  
给定一个包含n个整数的数组,要求将数组中的元素向前移动m个位置,即数组的前n-m个元素顺序向后移动m个位置,最后m个元素移动到数组的最前面,本文给大家介绍了如何使用Java解决数组旋转问题,需要的朋友可以参考下

问题描述

给定一个包含n个整数的数组,要求将数组中的元素向前移动m个位置,即数组的前n-m个元素顺序向后移动m个位置,最后m个元素移动到数组的最前面。例如,给定数组​​[1, 2, 3, 4, 5]​​和m=2,则数组变为​​[4, 5, 1, 2, 3]​​。

解决方案

方法一:使用额外数组

最直观的方法是使用一个额外的数组来存储旋转后的结果,然后将结果复制回原数组。这种方法简单易懂,但需要额外的空间。

Java代码实现

public class ArrayRotate {
    public static void rotate(int[] nums, int m) {
        if (nums == null || nums.length == 0) return;
        int n = nums.length;
        m %= n; // 处理m大于n的情况
        if (m == 0) return;

        int[] temp = new int[m];
        System.arraycopy(nums, n - m, temp, 0, m); // 复制最后m个元素到临时数组
        System.arraycopy(nums, 0, nums, m, n - m); // 将前n-m个元素向后移动m个位置
        System.arraycopy(temp, 0, nums, 0, m); // 将临时数组的内容复制到数组的最前面
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5};
        int m = 2;
        rotate(nums, m);
        for (int num : nums) {
            System.out.print(num + " ");
        }
    }
}

方法二:反转数组

更高效的方法是通过反转数组来实现旋转。具体步骤如下:

  1. 反转整个数组。
  2. 反转前m个元素。
  3. 反转剩余的n-m个元素。

这种方法不需要额外的空间,并且时间复杂度为O(n)。

Java代码实现

public class ArrayRotate {
    public static void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }

    public static void rotate(int[] nums, int m) {
        if (nums == null || nums.length == 0) return;
        int n = nums.length;
        m %= n; // 处理m大于n的情况
        if (m == 0) return;

        reverse(nums, 0, n - 1); // 反转整个数组
        reverse(nums, 0, m - 1); // 反转前m个元素
        reverse(nums, m, n - 1); // 反转剩余的n-m个元素
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5};
        int m = 2;
        rotate(nums, m);
        for (int num : nums) {
            System.out.print(num + " ");
        }
    }
}

这个问题可以通过多种方式解决,这里我将提供一个使用Java实现的示例代码。这个例子中,我们将使用数组来存储这些整数,并通过循环和临时数组来实现数组元素的旋转。

问题描述

给定一个包含 ​​n​​ 个整数的数组 ​​arr​​ 和一个整数 ​​m​​,我们需要将数组中的前 ​​n-m​​ 个元素向后移动 ​​m​​ 个位置,最后 ​​m​​ 个元素移动到数组的最前面。

示例

假设我们有一个数组 ​​arr = [1, 2, 3, 4, 5]​​ 和 ​​m = 2​​,那么经过操作后,数组应该变为 ​​[4, 5, 1, 2, 3]​​。

Java 实现

public class ArrayRotation {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int m = 2;
        
        // 调用旋转方法
        rotateArray(arr, m);
        
        // 打印旋转后的数组
        System.out.println("Rotated array:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }

    public static void rotateArray(int[] arr, int m) {
        int n = arr.length;
        if (n == 0 || m % n == 0) {
            return; // 如果数组为空或m是n的倍数,不需要旋转
        }

        m = m % n; // 处理m大于n的情况

        // 使用临时数组来存储最后m个元素
        int[] temp = new int[m];
        for (int i = 0; i < m; i++) {
            temp[i] = arr[n - m + i];
        }

        // 将前n-m个元素向后移动m个位置
        for (int i = n - m - 1; i >= 0; i--) {
            arr[i + m] = arr[i];
        }

        // 将临时数组中的元素放到数组的最前面
        for (int i = 0; i < m; i++) {
            arr[i] = temp[i];
        }
    }
}

代码解释

  1. 主方法 (main):
  • 定义一个数组 ​​arr​​ 和一个整数 ​​m​​。
  • 调用 ​​rotateArray​​ 方法进行数组旋转。
  • 打印旋转后的数组。
  1. 旋转方法 (rotateArray):
  • 获取数组的长度 ​​n​​。
  • 检查特殊情况:如果数组为空或 ​​m​​ 是 ​​n​​ 的倍数,则直接返回。
  • 计算 ​​m % n​​ 以处理 ​​m​​ 大于 ​​n​​ 的情况。
  • 使用一个临时数组 ​​temp​​ 来存储数组的最后 ​​m​​ 个元素。
  • 将数组的前 ​​n-m​​ 个元素向后移动 ​​m​​ 个位置。
  • 将临时数组 ​​temp​​ 中的元素放到数组的最前面。

运行结果

对于输入数组 ​​[1, 2, 3, 4, 5]​​ 和 ​​m = 2​​,输出将是:

Rotated array:
4 5 1 2 3

这个问题可以通过多种方法来解决,但这里我将介绍一种比较直观且效率较高的方法:通过三次反转数组来实现。

问题描述

给定一个整数数组 ​​nums​​ 和一个非负整数 ​​m​​,要求将数组的前 ​​n-m​​ 个元素向后移动 ​​m​​ 个位置,最后 ​​m​​ 个元素移到数组的最前面。

解决方案

  1. 反转整个数组:首先将整个数组反转。
  2. 反转前 m​ 个元素:然后将前 ​​m​​ 个元素反转。
  3. 反转剩余的 n-m​ 个元素:最后将剩余的 ​​n-m​​ 个元素反转。

具体步骤

假设我们有一个数组 ​​nums = [1, 2, 3, 4, 5]​​ 和 ​​m = 2​​,目标是将数组变为 ​​[4, 5, 1, 2, 3]​​。

  1. 反转整个数组
  • 原数组:​​[1, 2, 3, 4, 5]​
  • 反转后:​​[5, 4, 3, 2, 1]​
  1. 反转前 m​ 个元素
  • 前 ​​m​​ 个元素:​​[5, 4]​
  • 反转后:​​[4, 5]​
  • 当前数组:​​[4, 5, 3, 2, 1]​
  1. 反转剩余的 n-m​ 个元素
  • 剩余的 ​​n-m​​ 个元素:​​[3, 2, 1]​
  • 反转后:​​[1, 2, 3]​
  • 最终数组:​​[4, 5, 1, 2, 3]​

Java 实现代码

public class ArrayRotation {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5};
        int m = 2;
        rotate(nums, m);
        for (int num : nums) {
            System.out.print(num + " ");
        }
    }

    public static void rotate(int[] nums, int m) {
        if (nums == null || nums.length == 0 || m < 0) {
            throw new IllegalArgumentException("Invalid input");
        }
        
        int n = nums.length;
        m = m % n; // 处理 m 大于数组长度的情况
        
        reverse(nums, 0, n - 1); // 反转整个数组
        reverse(nums, 0, m - 1); // 反转前 m 个元素
        reverse(nums, m, n - 1); // 反转剩余的 n-m 个元素
    }

    private static void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
}

代码解释

  1. 主函数 main​:
  • 初始化数组 ​​nums​​ 和旋转次数 ​​m​​。
  • 调用 ​​rotate​​ 方法进行数组旋转。
  • 打印旋转后的数组。
  1. 旋转方法 rotate​:
  • 检查输入的有效性。
  • 计算实际需要旋转的步数 ​​m​​(处理 ​​m​​ 大于数组长度的情况)。
  • 调用 ​​reverse​​ 方法三次,分别反转整个数组、前 ​​m​​ 个元素和剩余的 ​​n-m​​ 个元素。
  1. 反转方法 reverse​:
  • 使用双指针法交换数组中的元素,从两端向中间逐步交换。

这种方法的时间复杂度为 O(n),空间复杂度为 O(1),非常高效。希望这个解释对你有帮助!如果有任何问题或需要进一步的说明,请随时告诉我。

以上就是使用Java解决数组旋转问题的方法详解的详细内容,更多关于Java解决数组旋转的资料请关注脚本之家其它相关文章!

相关文章

  • Java项目时的命名规范使用及说明

    Java项目时的命名规范使用及说明

    文章总结了SpringBoot项目命名规范,包括项目、包、类、方法、变量、配置文件、Starter、API、数据库和其它命名规则,以确保代码的一致性和可读性
    2026-01-01
  • CentOS7环境下安装JDK 1.8及解决wget命令缺失问题的办法

    CentOS7环境下安装JDK 1.8及解决wget命令缺失问题的办法

    在CentOS 7中wget命令是一个非常实用的工具,用于从互联网下载文件,然而默认情况下,wget可能未安装,这篇文章主要介绍了CentOS7环境下安装JDK 1.8及解决wget命令缺失问题的相关资料,需要的朋友可以参考下
    2025-10-10
  • 如何使用Java 8中DateTimeFormatter类型转换日期格式详解

    如何使用Java 8中DateTimeFormatter类型转换日期格式详解

    这篇文章主要介绍了如何使用Java 8中DateTimeFormatter类型转换日期格式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • springboot如何从数据库获取数据,用echarts显示(数据可视化)

    springboot如何从数据库获取数据,用echarts显示(数据可视化)

    这篇文章主要介绍了springboot如何从数据库获取数据,用echarts显示(数据可视化),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • java 增强型for循环语法详解

    java 增强型for循环语法详解

    增强型 for 循环(也称为 “for-each” 循环)是 Java 从 JDK 5 开始引入的一种便捷循环语法,旨在简化对数组或集合类的迭代操作,这篇文章主要介绍了java 增强型for循环 详解,需要的朋友可以参考下
    2025-04-04
  • 详解Java深拷贝,浅拷贝和Cloneable接口

    详解Java深拷贝,浅拷贝和Cloneable接口

    这篇文章主要为大家详细介绍了Java中Cloneable接口以及深拷贝与浅拷贝的相关知识,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-08-08
  • Java中CountDownLatch工具类详细解析

    Java中CountDownLatch工具类详细解析

    这篇文章主要介绍了Java中CountDownLatch工具类详细解析,创建CountDownLatch对象时,会传入一个count数值,该对象每次调用countDown()方法会使count -- ,就是count每次减1,需要的朋友可以参考下
    2023-11-11
  • Mybatis-Plus环境配置与入门案例分析

    Mybatis-Plus环境配置与入门案例分析

    MyBatis-Plus 是一个 Mybatis 增强版工具,在 MyBatis 上扩充了其他功能没有改变其基本功能,为了简化开发提交效率而存在,本篇文章带你配置环境并认识它
    2022-03-03
  • Java 非静态初始化的例子

    Java 非静态初始化的例子

    非静态初始化和静态初始化一模一样,只不过少了static关键字。但是如果两者共存的话,非静态初始化是比静态初始化慢一拍的。下边我们举两个例子来看一下。
    2020-09-09
  • Reactive Programming入门概念详解

    Reactive Programming入门概念详解

    这篇文章主要为大家介绍了Reactive Programming入门概念详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论