记10月11北航IGT笔试题—在一个array本身上排序
题目要求是这样的:
给一个数组,由三种字符组成,R,G,B,那么把这个数组重新排序,所有的R在最前面,所有的G在其次,所有的B在最后。排序要在O(n)的复杂度下完成,
不允许新身亲数组作为临时变量,不允许遍历数组多次。写出一种算法。
我的思路是这样的,假如一个数组为:RGGBGRBGRGGBBGGBRB......
A D
B C
定义四个指针,A,B从开始第一个非R的字符,C,D指向从开始第一个非B的字符。然后B向前移动,每次移动一位,如果该位置的字符为“R”那边把这个值变为A指针指向的值,而A指针指向的值变为R(实际上是A和B的值互换,使前面都是R),然后A的位置既然为“R”那么A指针向前移动,指向不是R的位置。同时,C也向前移动,每次移动一位,如果所指的位置的字符为“B”,那么D指针的值和C指针的值互换。(使后面都是B),然后D的位置既然是B,那么D指针向前移动,指向非“B”的位置。
什么时候完成这个算法呢?这是我在笔试时没考虑完全的地方,我开始认为,B向前移动到D指针的位置(后面全是B)了,或者C移动到A指针的位置(前面全是R)即可。这两者是‘||’的关系,实际上是不对的,B移动到D的位置,只能说明D前面的R全部移到了数组的开始位置,而A指针之后的B仍然没有全部移动到结尾处。所以只有满足,C指向A的位置,和B指向D的位置同时满足,才可以结束算法。
下面是代码:
void sortRGBarray(char *array,int length) { int a,b=0; int c,d=length-1; int i=0; int j=length-1; while(array[i]=='r') { a++; b++; i++; } while(array[length-1]=='B') { c--; d--; j--; } for(;a!=d&&c!=b;b++,c--) { if(array[a]=='r') a++; if(array[b]=='r') {array[b]=array[a]; array[a]='r' ; } if(array[c]=='b') {array[d]=array[c]; array[c]='b';} }
当然,这只是我的个人想法,期待有人有更好的算法。。。虽然这个博客看的人不多。。。

浙公网安备 33010602011771号