荷兰国旗问题

本文深入探讨了荷兰国旗问题,一种经典的排序算法挑战。通过详细解释和代码示例,阐述了如何在O(n)时间复杂度和O(1)空间复杂度下,将数组中的元素按特定条件分为三部分。理解这一算法有助于提升数据处理和排序技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法的意义:不在于你考虑大神们是怎么考虑到的方法,你为什么想不到。而是你在遇到相似的问题时候,能想起这种问题的解决方法。自己不是笨,他们当初遇到同样的问题时,也曾绞尽脑汁,只不过,他们更早的实践过了。

                                                                                                                     ------------2019.11.28日   于济南

荷兰国旗是由红白蓝3种颜色的条纹拼接而成,如下图所示:

假设这样的条纹有多条,且各种颜色的数量不一,并且随机组成了一个新的图形,新的图形可能如下图所示,但是绝非只有这一种情况:

需求是:把这些条纹按照颜色排好,红色的在上半部分,白色的在中间部分,蓝色的在下半部分,我们把这类问题称作荷兰国旗问题。

我们把荷兰国旗问题用数组的形式表达一下是这样的:

给定一个整数数组,给定一个值K,这个值在原数组中一定存在,要求把数组中小于K的元素放到数组的左边,大于K的元素放到数组的右边,等于K的元素放到数组的中间,最终返回一个整数数组,其中只有两个值,分别是等于K的数组部分的左右两个下标值。

要求额外空间复杂度O(1),时间复杂度O(n)

解这道题需要将数组划分为3部分,即小于num、等于num、大于num,这样一来我们建立三个索引,分别是左边界的,当前位置索引,右边界的索引,通过移动索引并交换位置即可得到答案。具体代码如下:

/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: Netherland
 * Author:   guangod
 * Date:     19-11-27 下午10:33
 * Description: 荷兰国旗问题
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package myalgorithms;

/**
 * 〈一句话功能简述〉<br>
 * 〈荷兰国旗问题〉
 * 要学会分析这种解法的来历,简单的问题往往可以看到更真实的思想
 *
 * @author guangod
 * @create 19-11-27
 * @since 1.0.0
 */
public class Netherland {
    public static int[] coreAlgorithms(int[] arr , int l , int r , int p) {
        int less = l - 1;//less代表左索引
        int more = r + 1;//more代表右索引
        while (l < more) {//l代表当前位置,p代表比较值
            if (arr[l] < p) swap(arr , ++ less , l++);
            else if (arr[l] > p) swap(arr , -- more , l);
            else l++;
        }
        return new int[] {less + 1 , more - 1};//less+1代表右索引的边界,more-1代表左索引的边界
    }
    public static void swap(int[] arr,int num1,int num2){
        int temp=arr[num1];
        arr[num1]=arr[num2];
        arr[num2]=temp;
    }
    public static int[] generateArray(){
        int[] arr =new int[10];
        for(int i=0;i<arr.length;i++){
            arr[i]=(int)(Math.random()*100);
        }
        return arr;
    }
    public static void printfArr(int[] arr){
        if(arr == null){
            return;
        }
        for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+" ");

        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] test=generateArray();
        printfArr(test);
        int[] res=coreAlgorithms(test,0,test.length-1,59);
        printfArr(test);
        System.out.println(res[0]);
        System.out.println(res[1]);
        //System.out.println(res[2]);
    }
}

 



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值