荷兰国旗问题 LeetCode排序问题

目录

问题描述

分析过程

代码实现


问题描述

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

分析过程

我们可以把这个模型抽象为:给定一个规范值(value)
等于value的放中间(白色)小于value的放左边(红)大于value的放右边(蓝)

设置一个小于区,一个大于区,对于index下标对应的值有如下的规则:
①如果<value则index所指的元素与小于区右边的前一个元素做交换 小于区右扩,index++
②如果=value则index++
③如果>value则让index所指的元素与大于区左边的前一个元素做交换 大于区右扩(此时index指向的是后面换过来的元素,该元素没有被判断过所以index不++)
当index==大于区的左界的时候 此时数组划分为了三块,<区 =区 >区 正如荷兰国旗一样分为三种颜色 红 白 蓝,但是注意了还没有结束
最后还要把规范值(相当于是=value的值)与大于区的左边界的第一个元素进行互换才行.
*/

代码实现

import java.util.Arrays;
import java.util.Stack;

public class Code2_PartitionTestAndQuickSortAndRandomQuickSort {
    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
  
    public static int[] partition(int[] arr,int l,int r){
        if(l>r){
        return new int []{-1,-1};
        }
        if(l==r){
            return new int[]{l,r};
        }
        //l<r
        int lessR=l-1;
        int moreL=r;
        int index=l;
        while(index<moreL){
            if(arr[index]==arr[r]){
                index++;
            }else if(arr[index]<arr[r]){
                swap(arr,++lessR,index++);
            }else{
                swap(arr,--moreL,index);
            }
        }
        swap(arr,r,moreL);
        int equalL=lessR+1;
        int equalR=moreL;
        return new int[]{equalL,equalR};
    }
    public static void quickSort(int[] arr){
            if(arr==null ||arr.length<2){
                return;}
            process(arr,0,arr.length-1);
    }
    public static void process(int[] arr,int l,int r){
        if(l>=r){
            return;
        }
        int[] partition = partition(arr, l, r);
        process(arr,l,partition[0]-1);
        process(arr,partition[1]+1,r);
    }
    public static void randomQuickSort(int[] arr){
        if(arr==null || arr.length<2){
            return;
        }
        process1(arr,0,arr.length-1);
    }

    public static void process1(int[] arr,int l,int r){
        if (l >= r) {
            return;
        }
        int[] partition = partition(arr, l, r);
        process1(arr,l,partition[0]-1);
        process1(arr,partition[1]+1,r );
    }

   public static class Info{
        int left;
        int right;

        public Info(int left, int right) {
            this.left = left;
            this.right = right;
        }
    }
    //非递归的方式实现随机快排(用栈代替系统栈)
    public static void randomQuickSort2 (int[] arr){
        if(arr==null || arr.length<2){
            return ;
        }
        int N=arr.length;
        swap(arr,N-1,(int)(Math.random()*N));
        int[] partition = partition(arr, 0, N - 1);
         Info infoLess=new Info(0,partition[0]-1);//小于区的区间信息
        Info infoMore=new Info(partition[1]+1,N-1);
        Stack<Info> stack=new Stack();
        stack.push(infoLess);
        stack.push(infoMore);
        while(!stack.isEmpty()){
            Info info = stack.pop();
            if(info.left<info.right){
                swap(arr,info.left+(int)(Math.random()*(info.right-info.left+1)),info.right);
                int[] partition1 = partition(arr, info.left, info.right);
                infoLess=new Info(info.left,partition1[0]-1);
                infoMore=new Info(partition1[1]+1,info.right);
                stack.push(infoLess);
                stack.push(infoMore);
            }
        }
    }





   


}

编写对数器


    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    public static int[] copyArray(int[] arr) {
        if (arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    public static void printArray(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 testTime = 10000;
        int maxSize = 10;
        int maxValue = 100;
        boolean succeed = true;
        System.out.println("test begin");
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
           randomQuickSort(arr1);
            randomQuickSort2(arr2);
            if (!isEqual(arr1, arr2)) {
                succeed = false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println("test end");
        System.out.println("测试" + testTime + "组是否全部通过:" + (succeed ? "是" : "否"));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值