荷兰国旗问题
代码是Javascript语言写的(几乎是伪代码)
问题描述
荷兰国旗问题 给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
解决思想
在数组两边个准备一个区域,一个小于num区域放在数组左边,一个大于num区域放在数组右边,通过对数组里的数字与num进行比较,如果小于num就将其放在小于区域,如果等于num则不动,比较下一个数字,如果大于则将其放在大于区域,类似于发货
分析记忆
为数组准备两个区域:{小于区域} [即将操作的数组] {大于区域}
我们定义两个下标用于确定两个区域的边界:
less初始停留在整个数组的最左边,表示小于区域没有数字,more初始停留在整个数组的最右边,表示大于区域没有数字,定义一个cur下标来记录待比较的数字,以及我们拿到一个num,这是整个的准备工作
随后进行比较的过程“类似于发货”
1)当cur指的数等于num,cur下标跳下一个继续比较,例如当num=5,cur指的数也是5
2)如果cur指的数小于num,则将cur指的数与小于区域下一个数交换,小于区域扩一下,cur跳下一个
3)如果cur指的数大于num,则将cur指的数与大于区域的前一个数交换,大于区域像前扩大一位,cur不动,继续比较换过来的数与num的大小,继续进行操作
当cur和more撞上的时候,整个发货过程结束,完成
因为cur和more必有一个在移动,小于等于过程cur移动,大于过程more移动,所以必撞在一起
代码实现
var partitionArr = [5,5,8,6,5,8,1,3,6,9,9];
function partition(arr,l,r,num){
var less = l-1;
var more = r+1;
var cur = l;
while(cur<more){
if(arr[cur]<num){
swap(arr, ++less, cur++);//小于区域扩大一位,cur向后移一位
}
else if(arr[cur]>num){
swap(arr, --more, cur);//大于区域扩大一位,cur不动,继续比较换过来的数
}
else{
cur++;
}
}
}
function swap(arr,i,j){
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
partition(partitionArr,0,partitionArr.length-1,5);
console.log(partitionArr);
运行结果: