leetcode
leetcode 251 ~ 300
摆动排序

摆动排序

难度:

标签:

题目描述

代码结果

运行时间: 16 ms, 内存: 16.8 MB


/*
 * 思路:
 * 使用Java Stream API并不适合直接实现摆动排序问题,
 * 因为流操作主要用于集合的数据处理,且不容易在流中进行索引操作和元素交换。
 * 因此,我们将使用标准的for循环来实现。
 */
import java.util.stream.IntStream;
public class WiggleSort {
    public void wiggleSort(int[] nums) {
        IntStream.range(0, nums.length - 1).forEach(i -> {
            if ((i % 2 == 0 && nums[i] > nums[i + 1]) || (i % 2 != 0 && nums[i] < nums[i + 1])) {
                // 交换元素
                int temp = nums[i];
                nums[i] = nums[i + 1];
                nums[i + 1] = temp;
            }
        });
    }
}
 

解释

方法:

该题解的思路是通过一次遍历对数组进行就地修改,让相邻两个元素满足摆动排序的要求。具体来说,对于偶数下标 i,如果 nums[i] > nums[i+1],就交换这两个元素;对于奇数下标 i,如果 nums[i] < nums[i+1],就交换这两个元素。这样遍历修改一遍后,整个数组就满足了摆动排序的要求。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中提到了对于偶数和奇数下标有不同的处理方式,你能解释为什么要这样分别处理吗?
摆动排序要求数组中相邻的元素之间交替大于和小于。对于偶数下标的元素,题解中保证它不大于其后的元素(偶数下标的元素应该小于或等于其后的元素),而对于奇数下标的元素,则确保它不小于其后的元素(奇数下标的元素应该大于或等于其后的元素)。这种处理方式是为了确保数组在遍历一次后,满足摆动的条件,即偶数位置的元素应较小,奇数位置的元素应较大,从而形成一种“摆动”的模式。
🦆
在交换元素时,如何确保交换后的数组满足摆动排序的定义?是否有可能交换后某些元素的顺序还是不符合要求?
通过对每一个元素进行条件判断并交换,算法确保了当前元素与其后一个元素满足摆动条件。但是,这种方法只保证了局部的正确性(即每对相邻元素),并没有全局的保障。理论上,通过这种一次遍历的方式,大多数情况下能够达成全局的摆动效果。然而,在某些特殊情况下(如多个相同的元素连续出现),可能在一次遍历后仍有不符合摆动排序的情况,需要进一步的验证或多次遍历来处理这种情况。
🦆
如果数组长度为奇数或偶数,该算法的处理方式有什么不同吗?是否所有情况下都能保证效果?
该算法对于数组长度是奇数或偶数处理方式相同,即通过遍历直至数组倒数第二个元素,并进行条件判断和交换。无论数组长度是奇数还是偶数,算法的基本逻辑不变。但是,不论数组的长度是奇数还是偶数,算法都可能在某些特定数据配置下无法完全达到全局的摆动效果,可能需要额外的遍历或其他技术手段来确保全局的摆动排序。
🦆
题解中使用了就地修改数组的方式,这种方法有没有可能影响到算法的稳定性或造成其他潜在问题?
就地修改数组的方式意味着原数组的元素会被直接交换,从而节省了额外的空间开销。然而,这种方法可能会影响算法的稳定性,特别是在多线程环境下或者数组中包含有重复元素时。因为就地修改不提供额外的空间缓冲,一旦修改过程中发生错误(如程序崩溃),原始数据可能丢失或损坏。此外,就地修改可能会造成元素的原始顺序丢失,这在需要保持元素原始顺序的上下文中可能是不可接受的。

相关问题

颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 12 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

 

示例 1:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

示例 2:

输入:nums = [2,0,1]
输出:[0,1,2]

 

提示:

  • n == nums.length
  • 1 <= n <= 300
  • nums[i]012

 

进阶:

  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

摆动排序 II

给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。

你可以假设所有输入数组都可以得到满足题目要求的结果。

 

示例 1:

输入:nums = [1,5,1,1,6,4]
输出:[1,6,1,5,1,4]
解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。

示例 2:

输入:nums = [1,3,2,2,3,1]
输出:[2,3,1,3,1,2]

 

提示:

  • 1 <= nums.length <= 5 * 104
  • 0 <= nums[i] <= 5000
  • 题目数据保证,对于给定的输入 nums ,总能产生满足题目要求的结果

 

进阶:你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?