【算法题】荷兰国旗问题[力扣75题颜色分类] - JAVA

一、题目

二、文字解释

1.1 前言

本题是经典的「荷兰国旗问题」,由计算机科学家 Edsger W. Dijkstra 首先提出。如同图中所示的荷兰国旗,其由红、白、蓝三色水平排列组成。在算法领域,该问题可类比为将一个由特定的三种元素(可抽象对应红、白、蓝)组成的数组,通过特定算法实现元素的有序排列,使得相同元素相邻,且按照类似荷兰国旗颜色顺序的规则分布。

1.2 三指针算法实现

Java 代码实现

public class Solution {
    public void sortColors(int[] nums) {
        int low = 0;
        int mid = 0;
        int high = nums.length - 1;
        
        while (mid <= high) {
            if (nums[mid] == 0) {
                // 交换 nums[low] 和 nums[mid]
                int temp = nums[low];
                nums[low] = nums[mid];
                nums[mid] = temp;
                low++;
                mid++;
            } else if (nums[mid] == 1) {
                mid++;
            } else { // nums[mid] == 2
                // 交换 nums[mid] 和 nums[high]
                int temp = nums[mid];
                nums[mid] = nums[high];
                nums[high] = temp;
                high--;
            }
        }
    }
}

1.3 实现细节

  1. 三指针定义
    • low:指向 0 元素的右边界,区间 [0, low-1] 中所有元素均为 0。
    • mid:当前遍历的指针,负责检查并处理每个元素。
    • high:指向 2 元素的左边界,区间 [high+1, n-1] 中所有元素均为 2。
  2. 交换逻辑
    • nums[mid] == 0 时:
      • nums[low]nums[mid] 交换,然后 low++mid++
      • 这确保了所有 0 都被移动到数组左侧。
    • nums[mid] == 1 时:
      • 无需交换,直接 mid++,因为 1 应该保持在中间位置。
    • nums[mid] == 2 时:
      • nums[mid]nums[high] 交换,然后 high--
      • 注意此时 mid 不移动,因为交换后的元素需要重新检查。
  3. 循环条件
    • mid <= high,确保遍历到所有未处理的元素。
    • mid > high 时,所有元素都已完成归类。

1.4 运行过程(以 [2,0,2,1,1,0] 为例)

  1. 初始状态:low=0, mid=0, high=5,数组:[2,0,2,1,1,0]
  2. nums[mid]=2:执行交换操作,nums[0]nums[5] 交换
    • 交换后数组:[0,0,2,1,1,2]high=4
  3. nums[mid]=0:执行交换操作,nums[0]nums[0] 交换(实际不变)
    • 数组保持:[0,0,2,1,1,2]low=1, mid=1
  4. nums[mid]=0:执行交换操作,nums[1]nums[1] 交换(实际不变)
    • 数组保持:[0,0,2,1,1,2]low=2, mid=2
  5. nums[mid]=2:执行交换操作,nums[2]nums[4] 交换
    • 交换后数组:[0,0,1,1,2,2]high=3
  6. nums[mid]=1:执行 mid++
    • 数组保持:[0,0,1,1,2,2]mid=3
  7. nums[mid]=1:执行 mid++
    • 数组保持:[0,0,1,1,2,2]mid=4
  8. 此时 mid=4 > high=3,算法终止。

1.5 时间与空间复杂度

  • 时间复杂度:O(n)
    • 算法只需对数组进行一次遍历,每个元素最多被交换一次。
    • 所有操作都是常数时间的简单比较和交换。
  • 空间复杂度:O(1)
    • 算法只使用了三个指针变量和一个临时变量进行交换。
    • 属于原地排序算法,不需要额外的空间。

要是对三指针算法不熟悉的可以去看我的三指针算法讲解
【算法基础】三指针排序算法 - JAVA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值