【算法实践】算法面试常见问题——数组的波浪排序

问题描述

给定一个无序整数数组,将其排列成波浪形数组。若数组 arr0..n-1 满足以下条件,则称为波浪形:

arr0 >= arr1 <= arr2 >= arr3 <= arr4 >= ...

或

arr0 <= arr1 >= arr2 <= arr3 >= arr4 <= ...

输入输出示例

示例 1

  • 输入: arr\[\] = {10, 5, 6, 3, 2, 20, 100, 80}
  • **输出:**arr\[\] = {10, 5, 6, 2, 20, 3, 100, 80}
  • 解释:
    输出数组满足 10 >= 5 <= 6 >= 2 <= 20 >= 3 <= 100 >= 80 的波浪形式。
    波浪形允许两种交替模式(大-小或小-大交替),只要保持上下交替即可。

示例 2

  • **输入:**arr\[\] = {20, 10, 8, 6, 4, 2}
  • **输出:**arr\[\] = {20, 8, 10, 4, 6, 2}
  • 解释:
    输出数组满足 20 >= 8 <= 10 >= 4 <= 6 >= 2 的波浪形式。

关键要求

  1. **交替规则:**相邻元素必须满足 >= 和 <= 交替出现。
  2. **多解性:**可能存在多个有效答案(如示例 1 的另一种解为 {5, 10, 2, 6, 3, 20, 80, 100})。
  3. **局部调整:**无需全局排序,只需保证局部交替关系。

算法思路(附加说明)

方法 1:排序后交换相邻元素

  • 步骤:
    1. 先对数组升序排序。
    2. 遍历数组,每两个相邻元素交换一次。
  • 复杂度:
    • 时间复杂度:O(n log n)(排序耗时)。
    • 空间复杂度:O(1)(原地操作)。

方法 2:单次遍历调整(推荐)

  • 核心思想:
    确保所有偶数位置元素大于等于其相邻元素,即可自动满足波浪条件。
  • 步骤:
    1. 遍历所有偶数索引位置(i = 0, 2, 4, ...)。
    2. 对每个位置 i:
      • 若 arri-1 > arri(且 i > 0),交换它们。
      • 若 arri+1 > arri(且 i < n-1),交换它们。
  • 复杂度:
    • 时间复杂度:O(n)(单次遍历)。
    • 空间复杂度:O(1)(原地操作)。

Java实现

java 复制代码
/**
 * 将无序数组排列成"波浪形"数组:
 * 满足 arr[0] >= arr[1] <= arr[2] >= arr[3]...
 * 或 arr[0] <= arr[1] >= arr[2] <= arr[3]...
 */

public class WaveArraySorter {
    /**
     * 交换数组中两个元素的位置
     * @param arr 目标数组
     * @param i 第一个元素的索引
     * @param j 第二个元素的索引
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * O(n)时间复杂度实现波浪排序的核心算法
     * 关键思想:确保所有偶数索引元素都大于相邻元素
     */
    public static void sortWave(int[] arr) {
        // 遍历所有偶数索引位置(0,2,4...)
        for (int i = 0; i < arr.length; i += 2) {           
            // 如果前一个元素更大,交换它们
            if (i > 0 && arr[i-1] > arr[i]) {
                swap(arr, i-1, i);
            }
           
            // 如果后一个元素更大,交换它们
            if (i < arr.length-1 && arr[i+1] > arr[i]) {
                swap(arr, i, i+1);
            }
        }
    }

    public static void main(String[] args) {
        // 测试用例1
        int[] arr1 = {10, 5, 6, 3, 2, 20, 100, 80};
        System.out.println("原始数组1:" + Arrays.toString(arr1));
        sortWave(arr1);
        System.out.println("波浪排序1:" + Arrays.toString(arr1));
        // 测试用例2
        int[] arr2 = {20, 10, 8, 6, 4, 2};
        System.out.println("\n原始数组2:" + Arrays.toString(arr2));
        sortWave(arr2);
        System.out.println("波浪排序2:" + Arrays.toString(arr2));
    }
}
相关推荐
动词ing28 分钟前
【题目练习】全排列
算法
易小尊1 小时前
Dixon-Coles 的 τ 函数,我写错了三次
算法
伤心的梧桐叶1 小时前
Picset与创客贴比等待时间,没做完的任务不能从表里消失
python
没有气的汽水1 小时前
一次 SQS 消费者静默退出的排查:问题最后竟然出在日志里
python
用户450030140231 小时前
物业催缴系统为什么总在"冷却"这一步翻车:账期建模与规则命中的几个取舍
python
Web极客码2 小时前
决策模型 + LLM:用 Python 拆解浏览器自动化工作流
java·python·自动化
fanruitian2 小时前
python 装饰器 闭包
python
凯瑟琳.奥古斯特2 小时前
力扣1015C++解法技巧
c++·算法·leetcode·链表·职场和发展
泡茶喝茶写代码2 小时前
A股量化策略回测实战:从行情数据到绩效评估(第 13 篇):放量突破策略
java·python·股票数据api·股票数据api接口·股票量化数据api·股票量化数据接口
seowmt2 小时前
GEO效果该什么时候看数据:从立项到复盘的时间线复盘
算法·ip·seo·geo·faq