数组先小于等于再大于等于的调整

给定数组 arr,请将数组调整成 a <= b >= c <= d >= e <= f...的样子

例如,arr = {3,1,2}
调整之后,arr 可以是{1,3,2}. 1 <= 3 >=2
调整之后,arr 也可以是{2,3,1}. 2 <= 3 >=1
arr = {3,1,2,6}
调整之后,arr 可以是{1,6,2,3}. 1 <= 6 >= 2 <= 3
调整之后,arr 也可以是{3,6,1,2}. 3 <= 6 >= 1 <= 2

1,如果 arr 长度为 N,要求时间复杂度为 O(N),额外空间复杂度为 O(1)。
2,arr 可能会不止一种调整方案,但只要满足要求即可。


算法原形:完美洗牌算法


public static void shuffle(int[] arr, int l, int r){
	while(r - l + 1 > 0){
		int lenAndOne = r - l + 2;
		int bloom = 3;
		int k = 1;
		while(bloom <= lenAndOne / 3){
			bloom += 3;
			k++;
		}
		int m = (bloom - 1) / 2;
		int mid = (l + r) / 2;
		rotate(arr, l + m, mid, mid+m);
		cycles(arr, l - 1, bloom, k);
		l = l + bloom - 1;
	}
}

public static void cycles(int[] arr, int base, int bloom, int k){
	for(int i = 0, trigger = 1; i < k; i++, trigger += 3){
		int next = (2*trigger) % bloom;
		int cur = next;
		int record = arr[next + base];
		int tmp = 0;
		arr[next + base] = arr[trigger + base];
		while(cur != trigger){
			next = (2 * cur) %bloom;
			tmp = arr[next + base];
			arr[next + base] = record;
			cur = next;
			record = tmp;
		}
	}
}

public static void rotate(int[] arr, int l, int m, int r){
	reverse(arr, l, m);
	reverse(arr, m + 1, r);
	reverse(arr, l ,r);
}

public static void reverse(int[] arr, int l, int r){
	while(l < r){
		int tmp = arr[l];
		arr[l++] = arr[r];
		arr[r--] = tmp;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值