从零开始学算法(五)荷兰国旗问题详解

本文深入讲解荷兰国旗问题的算法解决方案,介绍如何在O(N)时间复杂度和O(1)额外空间复杂度下,将数组中所有元素按指定数值分为三部分:小于、等于和大于该数值。通过具体步骤解析和代码实现,帮助读者理解这一经典排序问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从零开始学算法(五)荷兰国旗问题详解

荷兰国旗问题

代码是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);


运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值