荷兰国旗问题:
给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)。
实现思想:
当前数和num数比较,如果小于则当前数和小于区域的后一个数交换,如果大于则当前数和大于区域的前一个数交换,等于则当前数不变,指向下一个数再次进行比较,如果当前数和大于区域的第一个数相等时,则跳出循环,最后返回数组的值。
实现代码:
package basic_class_01;
public class NetherlandsFlags {
//构造一个类来实现算法
public static int[] partition(int[] arr,int l,int r,int num){
//l:0位置,r:数组末尾
int less=l-1;//小于num数的位置的下标
int more=r+1;//大于num数的位置的下标
while(l<more){//当等于num的下标等于大于数的下标开始则结束
if(arr[l]<num){//如果数小于num值
swap(arr,++less,l++);
//将小于num数区域最后一个数的下一个数和当前位置交换,当前数变为下一个数
}
else if(arr[l]>num){//如果数大于num
swap(arr,--more,l);
//将大于num数区域的第一个数的前一个数和当前数交换,此时得当前数接着比较
}
else{
l++;//与num相等不需要交换,当前数变为下一个
}
}
return arr;//返回交换好的数组
}
//交换函数
public static void swap(int[] arr,int i,int j){
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
public static void main(String[] args) {
int[] arr ={9,8,7,6,5,5,5,4,3,2,1};
//给定arr数组的内容,将小于num的数放在左边,等于放在中间,大于放在右边
arr = partition(arr,0,arr.length-1,5);
//调用类(数组,起点,终点,num值),然后传回数组arr
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);//输出改变后的数组值
}
}
}
输出:
1
2
3
4
5
5
5
6
7
8
9