快速排序与荷兰国旗问题
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(); } }