leetcode
leetcode 1901 ~ 1950
对奇偶下标分别排序

对奇偶下标分别排序

难度:

标签:

题目描述

代码结果

运行时间: 25 ms, 内存: 16.1 MB


// Java Stream Solution
// 思路:
// 使用Java Stream API来实现提取、排序和插入。
// 1. 使用IntStream.range提取奇数和偶数下标元素。
// 2. 使用stream的sorted方法进行排序,并将结果收集为数组。

import java.util.Arrays;
import java.util.stream.IntStream;

public class Solution {
    public int[] rearrangeArray(int[] nums) {
        int n = nums.length;
        // 提取奇数下标元素并按非递增排序
        int[] oddIndex = IntStream.range(0, n)
                                  .filter(i -> i % 2 == 1)
                                  .map(i -> nums[i])
                                  .boxed()
                                  .sorted((a, b) -> b - a)
                                  .mapToInt(i -> i)
                                  .toArray();
        // 提取偶数下标元素并按非递减排序
        int[] evenIndex = IntStream.range(0, n)
                                   .filter(i -> i % 2 == 0)
                                   .map(i -> nums[i])
                                   .sorted()
                                   .toArray();
        // 重新插入数组
        int oddPtr = 0, evenPtr = 0;
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                nums[i] = evenIndex[evenPtr++];
            } else {
                nums[i] = oddIndex[oddPtr++];
            }
        }
        return nums;
    }
}

解释

方法:

题解首先通过分割原数组 nums,将奇数下标和偶数下标的元素分别收集。使用 Python 列表切片操作,nums[::2] 获取所有偶数下标的元素,nums[1::2] 获取所有奇数下标的元素。随后对偶数下标的元素进行非递减排序,对奇数下标的元素进行非递增排序。非递增排序是通过先对元素进行非递减排序后再反转列表实现的。最后,将排序后的元素按原下标重新赋值给 nums,并返回修改后的 nums。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
你是如何保证在原地修改数组 nums 后,不会影响到后续对偶数或奇数下标元素的排序操作?
在 Python 中,使用切片操作如 nums[::2] 和 nums[1::2] 实际上是创建了原数组的副本,而不是直接操作原数组。这意味着当我们对 nums[::2] 进行排序时,我们实际上是在对其副本进行操作,排序完毕后再将排序后的副本赋值回原数组的相应位置。这个过程确保了对一个切片的修改不会影响到另一个切片。因此,先对偶数下标的元素进行排序并不会影响奇数下标元素的初始状态,反之亦然。
🦆
在实现非递增排序时,为什么选择先进行非递减排序再反转列表,而不是直接使用排序算法的降序功能?
虽然在某些编程语言中,排序函数提供了直接按降序排序的选项(例如 Python 的 sorted 函数可以通过设置参数 reverse=True 实现降序排序),但选择先按非递减排序再反转列表的做法可以更加直观地展示排序和反转的逻辑关系,并且保持代码的一致性和可读性。此外,对于初学者来说,这种方法能更清晰地理解排序后的数据结构变化。
🦆
如果输入数组 nums 的长度非常小(例如只有1或2个元素),此算法是否还能正确工作?如何处理这种边界情况?
此算法也适用于数组长度非常小的情况。如果数组只有一个元素,该元素既被视为偶数下标也是奇数下标的唯一元素,但由于排序和反转操作都不会改变单个元素的位置或值,所以算法仍然有效。如果数组有两个元素,第一个元素为偶数下标,第二个元素为奇数下标,它们各自被排序后仍会保持在原来的位置。因此,不需要特别的边界处理措施,算法在这些情况下都能正确执行。
🦆
在对偶数下标和奇数下标的元素进行排序时,这两个操作是否可以并行执行以提高效率?
理论上,由于偶数下标和奇数下标的元素排序是互不影响的,这两个操作可以通过并行执行来提高效率。在多线程或多进程的编程环境中,可以将偶数下标元素的排序和奇数下标元素的排序分配到不同的线程或进程中执行。然而,这种优化是否值得实施取决于原数组的大小以及系统对并行计算的支持。对于较小的数组,由于线程创建和管理的开销,这种优化可能不会带来显著的性能提升。

相关问题