荷兰国旗问题
int [ ] nums = { 1 , 2 , 3 , 4 , 6 , 7 , 10 , 9 , 123 , 3 }
int target = 10 ;
private int [ ] edges ( int [ ] nums, int L, int R, int target) {
int less = L - 1 ;
int more = R + 1 ;
int cur = L;
while ( cur < more) {
if ( nums[ cur] < target) {
less++ ;
int temp = nums[ less] ;
nums[ less] = nums[ cur] ;
nums[ cur] = temp;
cur++ ;
} else if ( nums[ cur] > target) {
int temp = nums[ cur] ;
more-- ;
nums[ cur] = nums[ more] ;
nums[ more] = temp;
} else {
cur++ ;
}
}
return new int [ ] { less, more} ;
}
快排
经典快排中一般每次以数组尾部元素作为标杆。 一次只处理一个元素,利用荷兰国旗问题或许一次可以处理一批元素=标杆的问题。 主要是使用荷兰国旗的代码,来完成快排。从而只需要掌握使得一套代码。
private void quickSort ( int [ ] nums) {
if ( nums. length < 2 ) {
return ;
}
quickSort ( nums, 0 , nums. length - 1 ) ;
}
private void quickSort ( int [ ] nums, int L, int R) {
if ( nums == null || L >= R) {
return ;
}
int [ ] ints = edges1 ( nums, L, R) ;
quickSort ( nums, L, ints[ 0 ] - 1 ) ;
quickSort ( nums, ints[ 1 ] + 1 , R) ;
}
private int [ ] edges1 ( int [ ] nums, int L, int R) {
int less = L - 1 ;
int target = nums[ R] ;
int more = R;
int cur = L;
while ( cur < more) {
if ( nums[ cur] < target) {
less++ ;
int temp = nums[ less] ;
nums[ less] = nums[ cur] ;
nums[ cur] = temp;
cur++ ;
} else if ( nums[ cur] > target) {
int temp = nums[ cur] ;
more-- ;
nums[ cur] = nums[ more] ;
nums[ more] = temp;
} else {
cur++ ;
}
}
int temp = nums[ R] ;
nums[ R] = nums[ more] ;
nums[ more] = temp;
return new int [ ] { less + 1 , more} ;
}
注意点
在寻找边缘数组中,more和less的初始值和返回值不太一样,主要是荷兰国旗中给定的target不一定在原数组中,因此荷兰国旗问题的less = L-1,more = R+1,即初始化成不存在的值。快排中标杆以最后一个元素作为target,这个值一定存在,因此more = R初始。 在返回less,more的数组中,其中[less+1,more]是值 = target的区间。