数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
2010-06-30 21:12
429 查看
题目:给定整数数组,元素为a1 a2 a3 .. an b1 b2 b3 .. bn元素个数为 2n
要求:请生成如下数组,a1 b1, a2 b2, a3 b3, .. an bn.
条件:时间复杂度为O(N),空间复杂度为O(1).
来源:http://topic.csdn.net/u/20100623/09/dd25166f-bac4-4b2d-98ab-71cab69f4241.html?54216
//***************************************************************************************
思路:
1、首先证明当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
2、其次证明对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
证明:
1、当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
首先,从新编号,从“a1 a2 a3 .. an b1 b2 b3 .. bn” 到“0, 1, ... ,2^k-1, 2^k,... ,2^(k+1)-1”。
设某元素原来的下标为i,变换后的下标为j,则有:j=(2*i)%(2*n-1)。 例如:1-->2 (a2-->a3), 2-->4 (a3-->a5)。
然后,从1,3,..., n-1依次执行变换。例如n=8,则有:
1-->2-->4-->8-->1
3-->6-->12-->9-->3
5-->10-->5
7-->14-->13-->11-->7
设从i(i=2*k+1)开始变换的一组下标的集合为Si,则可以证明,Si∩Sj=空集,且 ∪Si=全集。
所以,该变换的时间复杂度为O(N),空间复杂度为O(1)的算法。
2、对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
对任意n,有n=∑ck*x^k,其中ck=0或1。
因此,可以采用对任意ck=1的情况:
首先,做整体移位,两个2^k连续块放在一起(采用翻转法[1],时间复杂度为O(N),空间复杂度为O(1));
其次,对两个2^k连续块采用上面的算法;
然后,对剩余部分再采取前两步的方法,直到k=1。
例如n=11,则有:
第一次:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
变为 0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,10,19,20,21
然后 0,11,1,12,2,13,3,14,4,15,5,16,6,17,7,18, 8,9,10,19,20,21
第二次:
0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,10,19,20,21
变为 0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,19,20, 10,21
然后 0,11,1,12,2,13,3,14,4,15,5,16,6,17,7,18, 8,19,9,20, 10,21
证明对任意n该方法的时间复杂度为O(N),有两种证明方法:
1、采用master theorem[2],可直接证明。
2、到n=2^k-1时,该算法的时间复杂度最大。因此,只需证明此时的时间复杂度为O(N)。
利用等比数列,可以证明此结论。
算法与证明描述结束。
[1] 编程之美。问题2.17。
[2] 算法导论。定理4.1
要求:请生成如下数组,a1 b1, a2 b2, a3 b3, .. an bn.
条件:时间复杂度为O(N),空间复杂度为O(1).
来源:http://topic.csdn.net/u/20100623/09/dd25166f-bac4-4b2d-98ab-71cab69f4241.html?54216
//***************************************************************************************
思路:
1、首先证明当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
2、其次证明对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
证明:
1、当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
首先,从新编号,从“a1 a2 a3 .. an b1 b2 b3 .. bn” 到“0, 1, ... ,2^k-1, 2^k,... ,2^(k+1)-1”。
设某元素原来的下标为i,变换后的下标为j,则有:j=(2*i)%(2*n-1)。 例如:1-->2 (a2-->a3), 2-->4 (a3-->a5)。
然后,从1,3,..., n-1依次执行变换。例如n=8,则有:
1-->2-->4-->8-->1
3-->6-->12-->9-->3
5-->10-->5
7-->14-->13-->11-->7
设从i(i=2*k+1)开始变换的一组下标的集合为Si,则可以证明,Si∩Sj=空集,且 ∪Si=全集。
所以,该变换的时间复杂度为O(N),空间复杂度为O(1)的算法。
2、对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
对任意n,有n=∑ck*x^k,其中ck=0或1。
因此,可以采用对任意ck=1的情况:
首先,做整体移位,两个2^k连续块放在一起(采用翻转法[1],时间复杂度为O(N),空间复杂度为O(1));
其次,对两个2^k连续块采用上面的算法;
然后,对剩余部分再采取前两步的方法,直到k=1。
例如n=11,则有:
第一次:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
变为 0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,10,19,20,21
然后 0,11,1,12,2,13,3,14,4,15,5,16,6,17,7,18, 8,9,10,19,20,21
第二次:
0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,10,19,20,21
变为 0,1,2,3,4,5,6,7,11,12,13,14,15,16,17,18, 8,9,19,20, 10,21
然后 0,11,1,12,2,13,3,14,4,15,5,16,6,17,7,18, 8,19,9,20, 10,21
证明对任意n该方法的时间复杂度为O(N),有两种证明方法:
1、采用master theorem[2],可直接证明。
2、到n=2^k-1时,该算法的时间复杂度最大。因此,只需证明此时的时间复杂度为O(N)。
利用等比数列,可以证明此结论。
算法与证明描述结束。
[1] 编程之美。问题2.17。
[2] 算法导论。定理4.1
/** * @author Administrator * */ public class TestShuZushuanFa { /** * */ public TestShuZushuanFa() { // TODO 自动生成构造函数存根 } public static void test(int[] arr, int size) { int temp = arr[size / 2]; for (int i = size / 2; i != 1;) { arr[i] = arr[(i + (i % 2) * (size - 1)) / 2]; // 奇数加(数组长度-1)除以2 偶数直接除以2 i = (i + (i % 2) * (size - 1)) / 2; } arr[1] = temp; for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+","); } } /** * @param args */ public static void main(String[] args) { // TODO 自动生成方法存根 int[] number = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; test(number, 20); } }
相关文章推荐
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn ) 概论思想(perfect shuffle 算法)
- 输入a1,a2,...,an,b1,b2,...,bn, 将这个序列顺序改为a1,b1,a2,b2,a3,b3,...,an,bn
- 有个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后{a1,b1,a2,b2,....,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解
- 有一个带头结点的单链表L={a1,b1,a2,b2,...,an,bn},设计一个算法将其拆分成两个带头结点的单链表A和B,正序链表A={a1,a2,a3...,an},逆序链表B={bn,bn-1,
- Pairs Forming LCM 在a,b中(a,b<=n)(1 ≤ n ≤ 10^14),有多少组(a,b) (a<b)满足lcm(a,b)==n; lcm(a,b)=p1 ^ max(a1,b1) * p2 ^ max(a2,b2) *..........*pn ^ max(an,bn)
- 面试-链表逆置 作业手写一个单链表,并且实现单链表元素的逆置,(a0, a1,a2,a3,..an)-> (an,an-1,… a1, a0),算法的空间复杂度和时间复杂度经可能低
- 有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列。对于1<=i,j<=k,求k个最小的(ai+bj)。要求算法尽量高效。
- 有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列。对于1<=i,j<=k,求k个最小的(ai+bj)。要求算法尽量高效。
- 据说是G开头公司的面试题【输入a1,a2,...,an,b1,b2,...,bn】
- 问题描述:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn 要求: 用O(1)的空间代价, 在O(n)时间内把数组变成 a1 b1 a2 b2 a3 b3 ... an bn
- 正则表达式积累记录-a1,b1;a2,b2;a3,b3...格式
- 拆分单链表(a1,b1,a2,b2....an,bn)=(a1,...an)+(bn,...b1)
- 有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列,对于1<=i,j<=k,求k个最小的(ai+bj),要求算法尽量高效
- 行车(a1*b1+a1*b2+..a1*bn+a2*b1+...an*bn=(a1+..an)(b1+..bn) )
- zoj 3512 Financial Fraud 给定一个整数序列a1, a2, … , an,求一个不下降序列b1 ≤ b2 ≤ … ≤ bn,使得数列{ai}和{bi}的各项之差的绝对值之和 |
- QSignalMapper分类有序地处理大量信号(就是信号转发机制,A1,A2,A3,....>B>C)
- 给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数。
- 给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数。