面试题中的杂耍算法

田暗星 2010-06-23 09:06:10
题目:给定整数数组,元素为a1 a2 a3 .. an b1 b2 b3 .. bn元素个数为 2n
要求:请生成如下数组,a1 b1, a2 b2, a3 b3, .. an bn.
条件:时间复杂度为O(N),空间复杂度为O(1) <无任何提示条件下:2小时内完成>

解答思路如下:<伪代码>
void fun(const int array[], const int size)
{
int start = 1;
int pos = 1;
int count = 0;//O(N): N-2
int temp; //O(1)就是这里
while(count < size-2)
{
while(start对应值所在新位置的值 != pos对应值所在新位置的值) //有点拗口 呵呵自己去计算吧 很简单的
{
temp = pos对应值所在新位置的值;
array[pos对应值所在新位置] = array[pos];
count ++;
}
start += 2;
pos = start;
}
}


实例演示:
old: 01 02 03 04 05 06 07 08 11 12 13 14 15 16 17 18
new: 01 11 02 12 03 13 04 14 05 15 06 16 07 17 08 18

按照上述算法的生成过程如下:
start = 1 count = 4
11 02 04 03 06 07 08 05 12 13 14 15 16 17
start = 3 count = 4 + 4
11 02 12 03 06 04 08 05 15 13 14 07 16 17
start = 5 count = 4 + 4 + 2
11 02 12 03 13 04 08 05 15 06 14 07 16 17
start = 7 count = 4 + 4 + 2 + 4 = 14 == 16-2 //complete
11 02 12 03 13 04 14 05 15 06 16 07 17 08
加上首位元素即可符合要求
01 11 02 12 03 13 04 14 05 15 06 16 07 17 08 18
//至此已经搞定,是不是很有意思 呵呵
//欢迎大家讨论更巧妙的办法..
...全文
1677 37 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
John_Smith 2010-09-30
  • 打赏
  • 举报
回复
楼上的算法和实现都比较乱。
这里给出自己的算法分析,程序实现以及测试数据。欢迎一起探讨:
http://hi.baidu.com/junwu1/blog/item/7fe676d2682557dd562c8444.html
edan_deng 2010-07-01
  • 打赏
  • 举报
回复
edan_deng 2010-06-30
  • 打赏
  • 举报
回复
思路:
1、首先证明当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
2、其次证明对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。

详见:
http://blog.csdn.net/edan_deng/archive/2010/06/30/5703492.aspx
edan_deng 2010-06-30
  • 打赏
  • 举报
回复
思路:
1、首先证明当 n=2^k 时,存在时间复杂度为O(N),空间复杂度为O(1)的算法。
2、其次证明对任意n,存在时间复杂度为O(N),空间复杂度为O(1)的算法。

详见:
http://topic.csdn.net/u/20100623/09/dd25166f-bac4-4b2d-98ab-71cab69f4241.html?54216
高亮 2010-06-29
  • 打赏
  • 举报
回复
时间复杂度为O(N),空间复杂度为O(2)

如果变量i用参数size代替使用。原size参数用arr.length代替,可以满足空间复杂度为O(1)

也就是说,变量i用参数size代替,就能实现空间复杂度为O(1),参数size的值再用数组对你算。java可以,C++不行。

其实实现过程简单,就是把一个要移动的位置保存好(空间复杂度O(1)),然后就开始循环移动数组中的元素,移动完再把保存的元素放的合适的位置,正好完成。
高亮 2010-06-29
  • 打赏
  • 举报
回复


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;
}



run:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19]
成功生成(总时间:0 秒)
wuhaiyangdh 2010-06-24
  • 打赏
  • 举报
回复
飞雪,牛!
whg01 2010-06-23
  • 打赏
  • 举报
回复
应该是最快的方法了。
jokey514 2010-06-23
  • 打赏
  • 举报
回复
学习 搞的不错
wzyzb 2010-06-23
  • 打赏
  • 举报
回复
噢 原来是散粉的啊
mousetec 2010-06-23
  • 打赏
  • 举报
回复
世界杯散分10/31
  • 打赏
  • 举报
回复
两层while,,,

看不懂!
purkhet 2010-06-23
  • 打赏
  • 举报
回复
I think it is OK
cattycat 2010-06-23
  • 打赏
  • 举报
回复
hehe,re一下。
可惜看不到你的头像,我这里头像全是叉。
田暗星 2010-06-23
  • 打赏
  • 举报
回复
自己霸占1楼吧
baihacker 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 c6u5fyd 的回复:]
错了 3跳过 从5开始 若5也跳过就从7开始 类推..
[/Quote]
加O(n)的空间来进行判断是可以的。
baihacker 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 c6u5fyd 的回复:]
错了 3跳过 从5开始 若5也跳过就从7开始 类推..
[/Quote]
加O(n)的空间来进行判断是可以的。
田暗星 2010-06-23
  • 打赏
  • 举报
回复
错了 3跳过 从5开始 若5也跳过就从7开始 类推..
田暗星 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 baihacker 的回复:]

引用 25 楼 c6u5fyd 的回复:
1 3 5 7 9..这样确实存在问题
应该在每次开始时 判断一下 若开始位置存在 则跳过从下一个开始
比如 3时存在 就从7 开始

可以用temp 在每轮结束后 记录最后的位置 以便下次对比判断是否 跳过


我在十楼的代码中,use数组就是这样的,但是如果这样的话就不满足O(n)空间复杂度的需求了。
我一不小心看22的也看成出错的……
[/Quote]
那么现在 判断跳过 是否就行了呢?
baihacker 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 c6u5fyd 的回复:]
1 3 5 7 9..这样确实存在问题
应该在每次开始时 判断一下 若开始位置存在 则跳过从下一个开始
比如 3时存在 就从7 开始

可以用temp 在每轮结束后 记录最后的位置 以便下次对比判断是否 跳过
[/Quote]

我在十楼的代码中,use数组就是这样的,但是如果这样的话就不满足O(n)空间复杂度的需求了。
我一不小心看22的也看成出错的情况了。
加载更多回复(17)

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧