荷兰国旗问题

问题:
给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。
要求额外空间复杂度O(1),时间复杂度O(N)

思路:
在这里插入图片描述

从第一个数开始逐个与num比较如果小于num则和小于num区域的下一个位置的数交换,小于num区域扩大1,也就是less加一,cur也加1向后移动一个,指向下一个需要比较的数,如果大于num则将cur指向的数和大于num区域的前一个位置的数交换,大于num区域扩大一,也就是more–,但是cur不动,将交换过来的数再与num进行比较,如果cur指向的数等于num,则位置不动,cue在指向下一个数

假设给定一组数据 5,3,5,2,8,7,4
数组的下标为0,1,2,3,4,5,6 num = 5
设置三个个变量一个为less,指向下标-1位置,另一个为more指向下标为7的位置,也就是arr.length位置,cur指向数组第一个数,也就是需要和num比较的数,0 - less为小于num的区域,more的右边为大于num区域,中间为等于num区域,对于第一个数5 = num,所以5的位置不动,cur向后移动一个,
数据:5,3,5,2,8,7,4
第二个数3 < num,所以3和5交换位置,小于num的区域扩大1,也就是less加一,此时小于num区域中有一个值为3,cur向后移动一个,
数据:3,5,5,2,8,7,4
第三个数5 = num,所以位置不动,cur向后移动一个,
数据:3,5,5,2,8,7,4
第四个数2 < num,所以2和小于num区域的下一个数交换位置,然后小于num区域扩大1,cur向后移动一个,此时小于num区域有两个数3和2,
数据:3,2,5,5,8,7,4
第5个数8 > num,让8和more位置前面位置4交换,more减一,也就是大于num的范围扩大1,此时大于num区域的值为8,
数据:3,2,5,5,4,7,8
此时cur位置不动仍然指向4,比较4和num的大小,因为4 < num,所以将4和小于num区域的下一个数5交换,cur向后移动一个,
数据:3,2,4,5,5,7,8
第六个数7 > num 所以让7和大于num区域前面位置的数交换,也就是和他本身进行交换,大于num区域扩大1,也就是more减一,因为more = num,也可以说因为此时已经划分好数据所属的区域,所以结束,
数据:3,2,4,5,5,7,8
代码实现:

	public static void 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++;
			}
		}
	}
	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值