RGB排序,一个字符串,里面只有三种字符R G B,所有的R都在G的前面,所有的G都在B的前面。将给定字符串按照此规律排序。要求不允许用辅助空间,复杂度控制在O(N)。遍历一遍就排好序。
设原来的的字符串为:
RGBBGRRBRGRBBG
解题思路:<本道题难在如何控制时间复杂度和空间复杂度>
1.如何解决空间复杂度问题
使用指针进行址传递而非值传递,可有效避免开辟额外的辅助空间,从而降低空间复杂度。
2.如何解决时间复杂度问题
定义3个char型指针变量R,G,B分别指向字符数组的始位,第二位和末位,
判断G的值,如果是’R’就与前面的R交换,然后指针R向后移动一位
如果是’B’就与后面的B交换,然后指针B向前移动一位
如果是’G’ 就将指针G向后移动一位
如此循环 直到指针G与指针B相遇,保证指针R之前的字符都为’R’,指针B之后的字符都为’B’,剩下中间的字符都为’G’
伪码表示如下:
while G<=B
if G=‘R’
交换G与R的值
R++
else
if G=‘B’
交换G与B的值
B–``
else
G++
C++程序代码如下
#include<iostream>
using namespace std;
int main()
{
char P[100];
int num,i;
void sort_RGB(char P[],int num);
for(i=1;(P[i]=getwchar())!='\n';i++)
{
if(P[i]!='R'&&P[i]!='G'&&P[i]!='B')
{
cout<<"请勿输入非法字符"<<endl;
return false;
}
num=i;
}
sort_RGB(P,num);
for(i=1;i<=num;i++)
cout<<P[i];
cout<<endl;
return 0;
}
void sort_RGB(char P[],int num)
{
char *R=&P[1],*B=&P[num],*G=&P[2],temp;
while(G<=B)
{
if(*G=='R')
{
temp=*R;*R=*G;*G=temp;
R++;
continue;
}
if(*G=='B')
{
temp=*B;*B=*G;*G=temp;
B--;
continue;
}
if(*G=='G')
{
G++;
continue;
}
}
}
分析算法sort_RGB的时间复杂度W(n)
在最坏情况下需进行n次循环,每次循环进行3次赋值操作(交换数值),所以W(n)=3n=O(n),满足题目要求
分析算法sort_RGB的空间复杂度S(n)
因为算法使用指针进行址传递,并没有开辟额外的辅助空间,虽然定义了的三个指针变量和整形变量temp,但内存需求很低仅占几个字节,满足题目要求
(PS:学生党原创,有问题欢迎各位大佬指出)