boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 前几天那个关于正负数stable排序的问题的帖子
相关主题
再来讨论一个题!
讨论一道老题:分离数组中的正负数 (转载)
再贴这道算法题,寻答案,有包子送
讨论下找两个元素和为0的题延伸
“常数空间O(N),O(1)算法那个题目”的变形题目
merge a1,a2,..b1,b2 to a1b1a2b2..
CCup题目2.1是不是有更简单的O(n)的解
G家onsite面经,求bless,顺便问问这情况能有戏吗
求教两道面试题
反interleave该怎么做?
相关话题的讨论汇总
话题: start话题: left话题: end话题: int话题: reverse
进入JobHunting版参与讨论
1 (共1页)
c*********t
发帖数: 2921
1
谁有那个帖子的link?好像那个帖子消失了。
好像是说给了一个整数array,有正数,有负数,要求把负数放在前面,正数放在后面,
同时保持顺序不变。
给个例子:
5 3 -2 9 -8 4 7 -10 6
结果应该是
-2 -8 -10 5 3 9 4 7 6
好像要求是O(n), in-place
大家讨论的结论是:
如果in-place,不可能O(n);
如果可以用额外的空间,可以很容易做到O(n).
有个人提到in-place,可以O(n logn),他没有说如何实现,这个如何做?我实在想不出
来。
我只能想出O(n^2) 的in-place的方法。
r*******y
发帖数: 1081
2
coask

【在 c*********t 的大作中提到】
: 谁有那个帖子的link?好像那个帖子消失了。
: 好像是说给了一个整数array,有正数,有负数,要求把负数放在前面,正数放在后面,
: 同时保持顺序不变。
: 给个例子:
: 5 3 -2 9 -8 4 7 -10 6
: 结果应该是
: -2 -8 -10 5 3 9 4 7 6
: 好像要求是O(n), in-place
: 大家讨论的结论是:
: 如果in-place,不可能O(n);

d*******d
发帖数: 2050
3
divide and conquer
直接写的,没试过,不知道对不对.
int switch(int * a, int start, int end){
if( start > end)
return -1;
if( start == end){
if( a[start] < 0)
return 1;
else
return 0;
int mid = (start+ end)/2;
int left = switch(a, start, mid);
int right = switch(a, mid+1, end);
int total_neg = 0;
if( left>0)
total_neg+= left;
if( right>0)
total_neg+= right;
if( right > 0 && mid-start+1 - left >0 ){
reverse(a, start+left+1, mid+right);
reverse(a, start+left+1, start+left+right);
reverse(a, start+left+right+1, mid+right);
}
return total_neg;
}
f****4
发帖数: 1359
c*********t
发帖数: 2921
5
谢谢!你的方法很好。
我想到了分治法,可是当时不知道如何把已经排好序的两段如何merge.
你用了类似于rotate string的方法来实现in-place rotate,把第一段里的正数部分和
第二段里的负数部分rotate.

【在 d*******d 的大作中提到】
: divide and conquer
: 直接写的,没试过,不知道对不对.
: int switch(int * a, int start, int end){
: if( start > end)
: return -1;
: if( start == end){
: if( a[start] < 0)
: return 1;
: else
: return 0;

m**q
发帖数: 189
6
赞!这个in-place的rotate在这类题目里面还是挺有用的
略微扩展一下,如果原题目要把数组划分成负数,0,整数,
并保持原来的顺序,可以先把0从数组中删掉,然后用
这个分治的算法,最后再把0加进来就行。
刚想起来一个以前看过的类似的问题,也是用分治的方法解决,
复杂度O(nlgn)
把数组A1, A2, ..., An, B1, B2, ..., Bn 变为
A1, B1, A2, B2, ..., An, Bn,
一个例子: abcdefg1234567 -> a1b2c3d4e5f6g7
用O(n)的in-place rotate方法,把数组分成两半
abcd1234 efg567
然后递归处理每个子问题就可以了,区别是这里
要先rotate再分治,原题是先分治再rotate

【在 c*********t 的大作中提到】
: 谢谢!你的方法很好。
: 我想到了分治法,可是当时不知道如何把已经排好序的两段如何merge.
: 你用了类似于rotate string的方法来实现in-place rotate,把第一段里的正数部分和
: 第二段里的负数部分rotate.

c*********t
发帖数: 2921
7
maxq,
你说的方法来interleave 数组A, B,我写了代码好像不work.
可能是我写错了,还是你的方法有问题?
http://www.mitbbs.com/article_t/JobHunting/31946827.html
的第二题就是问的这个问题。
你能给详细解答一下吗?

【在 m**q 的大作中提到】
: 赞!这个in-place的rotate在这类题目里面还是挺有用的
: 略微扩展一下,如果原题目要把数组划分成负数,0,整数,
: 并保持原来的顺序,可以先把0从数组中删掉,然后用
: 这个分治的算法,最后再把0加进来就行。
: 刚想起来一个以前看过的类似的问题,也是用分治的方法解决,
: 复杂度O(nlgn)
: 把数组A1, A2, ..., An, B1, B2, ..., Bn 变为
: A1, B1, A2, B2, ..., An, Bn,
: 一个例子: abcdefg1234567 -> a1b2c3d4e5f6g7
: 用O(n)的in-place rotate方法,把数组分成两半

d*******d
发帖数: 2050
8
这个问题要考虑分治后每个subproblem的奇偶问题.
你自己再研究研究,不行我再贴code

【在 c*********t 的大作中提到】
: maxq,
: 你说的方法来interleave 数组A, B,我写了代码好像不work.
: 可能是我写错了,还是你的方法有问题?
: http://www.mitbbs.com/article_t/JobHunting/31946827.html
: 的第二题就是问的这个问题。
: 你能给详细解答一下吗?

f*******t
发帖数: 7549
9
请贴code吧。。。有个问题我不知道怎么解决:当n=5的时候,rotate不是简单的交换。
a1a2a3a4a5b1b2b3b4b5 -> a1a2a3b1b2b3a4a5b4b5
需要把b的前三项与a的后两项交换
程序实在不知道怎么写

【在 d*******d 的大作中提到】
: 这个问题要考虑分治后每个subproblem的奇偶问题.
: 你自己再研究研究,不行我再贴code

d*******d
发帖数: 2050
10
好吧,如下code是我当练习直接写的,没有验证,
有问题的话,我再去把正确code翻出来
void swap(char * a, int start, int n){
for( int i = 0; i< n; i++){
char temp = a[start + i];
a[start+i] = a[start+i-n];
a[start+i-n] = temp;
}
}
void shiftpos(char * a, int start, int end){
if( end - start <= 1)
return;
int first_half_end = (end + start)/2;
int first_half_n = first_half_end - start + 1;
swap(a,first_half_end+1, first_half_n/2);
shiftpos(a, start, first_half_end);
if( first_half_n & 1){
shiftpos(a, first_half_end, end);
}else{
shiftpos(a, first_half_end+1, end);
}
}
相关主题
讨论下找两个元素和为0的题延伸
“常数空间O(N),O(1)算法那个题目”的变形题目
merge a1,a2,..b1,b2 to a1b1a2b2..
CCup题目2.1是不是有更简单的O(n)的解
进入JobHunting版参与讨论
c******o
发帖数: 534
11
这个swap是O(n)?

【在 d*******d 的大作中提到】
: 好吧,如下code是我当练习直接写的,没有验证,
: 有问题的话,我再去把正确code翻出来
: void swap(char * a, int start, int n){
: for( int i = 0; i< n; i++){
: char temp = a[start + i];
: a[start+i] = a[start+i-n];
: a[start+i-n] = temp;
: }
: }
: void shiftpos(char * a, int start, int end){

c******o
发帖数: 534
12
这个容易懂,谢谢了

【在 d*******d 的大作中提到】
: divide and conquer
: 直接写的,没试过,不知道对不对.
: int switch(int * a, int start, int end){
: if( start > end)
: return -1;
: if( start == end){
: if( a[start] < 0)
: return 1;
: else
: return 0;

f*******t
发帖数: 7549
13
应该是对的,感谢分享!

【在 d*******d 的大作中提到】
: 好吧,如下code是我当练习直接写的,没有验证,
: 有问题的话,我再去把正确code翻出来
: void swap(char * a, int start, int n){
: for( int i = 0; i< n; i++){
: char temp = a[start + i];
: a[start+i] = a[start+i-n];
: a[start+i-n] = temp;
: }
: }
: void shiftpos(char * a, int start, int end){

c*********t
发帖数: 2921
14
Dino,
你太牛了。对的。
你能不能说说你的rationale?
你是怎么想到了如果前半部分个数是奇数,第二个subproblem的时候就是从mid开始?
如果前半部分个数是偶数,第二个subproblem的时候就是从mid+1开始?
另外你是如何 figure out 按照前半段的一半的长度来交换的?
比如 a b c 1 2 3 ===> a b 1 c 2 3
谢谢!

【在 d*******d 的大作中提到】
: 好吧,如下code是我当练习直接写的,没有验证,
: 有问题的话,我再去把正确code翻出来
: void swap(char * a, int start, int n){
: for( int i = 0; i< n; i++){
: char temp = a[start + i];
: a[start+i] = a[start+i-n];
: a[start+i-n] = temp;
: }
: }
: void shiftpos(char * a, int start, int end){

r*******g
发帖数: 1335
15
这种题现场做很难做到bugfree啊,知道思路了就是这个奇偶问题都要把人弄死。。。

【在 c*********t 的大作中提到】
: Dino,
: 你太牛了。对的。
: 你能不能说说你的rationale?
: 你是怎么想到了如果前半部分个数是奇数,第二个subproblem的时候就是从mid开始?
: 如果前半部分个数是偶数,第二个subproblem的时候就是从mid+1开始?
: 另外你是如何 figure out 按照前半段的一半的长度来交换的?
: 比如 a b c 1 2 3 ===> a b 1 c 2 3
: 谢谢!

f*******t
发帖数: 7549
16
我还专门研究过,程序运行是以下步骤:
start: a b c 1 2 3
swap: a b 1 c 2 3
shift first half: [a b 1] c 2 3 -> a 1 b c 2 3
shift second half: a 1 [b c 2 3] -> a 1 b 2 c 3
done
dino这程序太牛了,完美解决奇偶性的问题

【在 c*********t 的大作中提到】
: Dino,
: 你太牛了。对的。
: 你能不能说说你的rationale?
: 你是怎么想到了如果前半部分个数是奇数,第二个subproblem的时候就是从mid开始?
: 如果前半部分个数是偶数,第二个subproblem的时候就是从mid+1开始?
: 另外你是如何 figure out 按照前半段的一半的长度来交换的?
: 比如 a b c 1 2 3 ===> a b 1 c 2 3
: 谢谢!

h******3
发帖数: 351
17
I am not sure I understand the solution correctly.
Let's consider this input:
{3,5,4,-2,-3,-1}
expected output should be
{-2,-3,-1,3,5,4}
consider the stack information of the final step:
start = 0; end = 5; left = 0; right = 3; mid = 2
reverse(start+left+1, mid+right)-> reverse{5,4,-2,-3,-1}, we get {3,-1,-3,-2
,4,5}
reverse(start+left+1, start+left+right)-> reverse{-1,-3,-2} we get
{3,-2,-3,-1,4,5}
reverse(start+left+right+1, mid+right)->reverse{4,5} we get
{3,-2,-3,-1,5,4}
which is not correct.
I think the first index of the first two reverse should start+left instead
of start+left+1.

【在 d*******d 的大作中提到】
: divide and conquer
: 直接写的,没试过,不知道对不对.
: int switch(int * a, int start, int end){
: if( start > end)
: return -1;
: if( start == end){
: if( a[start] < 0)
: return 1;
: else
: return 0;

k*j
发帖数: 153
18
这个是O(nlgn),不是O(n)吧?

【在 d*******d 的大作中提到】
: divide and conquer
: 直接写的,没试过,不知道对不对.
: int switch(int * a, int start, int end){
: if( start > end)
: return -1;
: if( start == end){
: if( a[start] < 0)
: return 1;
: else
: return 0;

s**x
发帖数: 405
19
this problem is at least as difficult as the in-place perfect shuffle
problem (turn 1A2B3C4D5E to 12345ABCDE in O(1) space and O(n) time); the
latter can be viewed as a special case
c*********t
发帖数: 2921
20
shyx,
turn 1A2B3C4D5E to 12345ABCDE

turn 12345ABCDE to 1A2B3C4D5E
是不是一样的难?是不是这两个题的思路差不多?
谢谢!

【在 s**x 的大作中提到】
: this problem is at least as difficult as the in-place perfect shuffle
: problem (turn 1A2B3C4D5E to 12345ABCDE in O(1) space and O(n) time); the
: latter can be viewed as a special case

k*j
发帖数: 153
21
想请教一下各位,这个dino提出的in-place rotate的方法为什么是O(n)的?
f(n) = 2f(n/2)+O(n),应该是O(nlgn)吧?

【在 m**q 的大作中提到】
: 赞!这个in-place的rotate在这类题目里面还是挺有用的
: 略微扩展一下,如果原题目要把数组划分成负数,0,整数,
: 并保持原来的顺序,可以先把0从数组中删掉,然后用
: 这个分治的算法,最后再把0加进来就行。
: 刚想起来一个以前看过的类似的问题,也是用分治的方法解决,
: 复杂度O(nlgn)
: 把数组A1, A2, ..., An, B1, B2, ..., Bn 变为
: A1, B1, A2, B2, ..., An, Bn,
: 一个例子: abcdefg1234567 -> a1b2c3d4e5f6g7
: 用O(n)的in-place rotate方法,把数组分成两半

1 (共1页)
进入JobHunting版参与讨论
相关主题
反interleave该怎么做?
一题貌似在AMAZON和MICROSOFT都出现过的题目。
这个rotated sorted array问题
leetcode 中部分binary search 总结
leetcode 新题findMin2 大家给挑挑毛病。
LC的search rotated array 2是不是搞错了?
算法题目一问
请教一个面试问题,careercup上的
一道google面试题的讨论
这题有啥好思路吗
相关话题的讨论汇总
话题: start话题: left话题: end话题: int话题: reverse