快速排序与荷兰国旗问题

1.问题描述:

  我们将乱序的红白蓝三色小球排列成有序的红白蓝三色的同颜色在一起的小球组。这个问题之所以叫荷兰国旗,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。

2.荷兰国旗问题与数组:

  给定一个数组arr,和一个数num,请把小于num的数放到数组的左边,等于num的数放在数组的中间,将大于Num的数放到数组的右边,额外空间复杂度为O(1),时间复杂度为O(N)

3.java实现

 

public class NetherLandsFlags {
    /*
    *
    *  在一个无序的随机大小数组中,把元素分成三部分存放,
    *  大于x放前面,等于x放中间,大于x放后面。不用管大于x或者小于x元素在数据中的顺序问题。
    *  对于此问题而言快速排序是解决问题最好的算法
    * */
    public static void main(String[] args) {
        int[] arr = generateRandomArray();
        printArray(arr);
        int[] res = partition(arr,0,arr.length-1,1);
        printArray(arr);
        System.out.println(res[0]);
        System.out.println(res[1]);
    }
    //这里l和r表示在l和r上进行值的划分
    public static int[] partition(int[] arr,int l,int r,int num){
       int less = l - 1 ;
       int more = r + 1 ;
       int cur = l;
        while (cur<more){
            if(arr[cur]<num){
                //交换数组中两个元素的位置
                swap(arr,++less,cur++);
            }
            else if(arr[cur]>num){
                swap(arr,--more,cur);
            }else {
                cur++;
            }
        }
        //返回的是处在数组中的左边界和右边界
        return new int[]{less+1,more-1};
    }
    //交换数组中两个元素的位置
    public static void swap(int[] arr,int i,int j){
        int temp = arr[i] ;
        arr[i] = arr[j];
        arr[j] =temp;
    }
    public static int[] generateRandomArray(){
        int[] arr= new int[10];
        for(int i =0 ;i<arr.length;i++){
            arr[i] = (int)(Math.random()*3);
        }
        return arr;
    }
    public static int[] copyArray(int[] arr){
        if(arr==null || arr.length==0){
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0 ; i<arr.length;i++){
            res[i] = arr[i];
        }
        return res;
    }
    public static void printArray(int[] arr){
        for (int i =0 ;i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
}

 

转载于:https://www.cnblogs.com/bigdata-stone/p/10482772.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值