首页 > 解决方案 > 在指定范围之间旋转数组中的元素

问题描述

我有一个数组:

int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};

我想将数组从指定范围旋转k几次,即从第 5 个元素到最后一个元素:

output: {1, 2, 3, 4, 9, 8, 5, 6, 7}

我试图调整算法以从数组的开始旋转到结束

public static int[] rotate(int[] nums, int k) {
    int[] a = new int[nums.length];
    for (int i = 4; i < nums.length; i++) {
        a[(i + k) % nums.length] = nums[i];
    }
    for (int i = 4; i < nums.length; i++) {
        nums[i] = a[i + 4];
    }
    return nums;
}

但是,输出是:1 2 3 4 0 0 5 6 7

除了将原始数组中的目标元素复制到临时数组中然后运行该算法之外,我做错了什么?为什么0, 0返回而不是9, 8

标签: javaarraysrotationarray-algorithms

解决方案


按指定步长在指定范围内旋转数组中的元素:

  1. 将数组拆分为三个部分beforerangeafter

  2. 移动指定范围的数组。

    2.1。将此范围分成两部分:nearfar

    2.2. 交换它们并连接回来。

  3. 将所有内容连接回来。

public static void main(String[] args) {
    int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int[] rotated = rotateRange(arr, 4, arr.length, 3);
    System.out.println(Arrays.toString(rotated));
    // [1, 2, 3, 4, 8, 9, 5, 6, 7]
}
// rotate a specified range of an array by a specified step
static int[] rotateRange(int[] arr, int start, int end, int n) {
    return Stream.of(
            // three parts: 'before', 'range' and 'after'
            Arrays.stream(arr, 0, start),
            // get a specified range and rotate it by a specified step
            Arrays.stream(rotate(Arrays.copyOfRange(arr, start, end), n)),
            Arrays.stream(arr, end, arr.length))
            // flatten into one stream
            .flatMapToInt(Function.identity())
            // return an array
            .toArray();
}
// rotate an array by a specified step
static int[] rotate(int[] arr, int n) {
    // prevent circular rotation
    n = n % arr.length;
    return IntStream.concat(
            // concatenate the two parts: 'far' and 'near'
            Arrays.stream(arr, n, arr.length),
            Arrays.stream(arr, 0, n))
            // return an array
            .toArray();
}

另请参阅:仅使用一个分号在 Java 中旋转 int 数组


推荐阅读