题目:给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。

解析:本题的解法类似于快速排序partition算法,对于字符串str,利用两个下标start1,end1,start1初始时指向字符串的头部,end1初始时指向字符串的尾部,当str[start1]!='R',str[end1]!='B'时候,不能简单像原来的partition那样直接作交换,而是要根据不同的情况做不同的处理,因为字符串中还包含第三类字符'G'。

C ++代码如下:

#include<iostream>
#include<cstring>
using namespace std;
const int MAXLEN=100;//字符串的最大长度
void Set_RGB(char *str);//位置调整函数,借助了快排的partition函数思想
int main()
{
char str[MAXLEN+1];
cin>>str;//输入只包含'R','G','B'的字符串
Set_RGB(str);
cout<<str<<endl;//输出调整过的字符串
return 0;
}
void Set_RGB(char *str)
{
if(str==NULL)
return;
int len=strlen(str);
int start1,end1,start2,end2;
char tmp;
start1=start2=0;
end1=end2=len-1;
while(true)
{
while(str[start1]=='R'&&start1<=end1)
{
start1++;
if(start1>start2)
start2=start1;//保证start2始终等于或大于start1
}
while(str[end1]=='B')
{
end1--;
if(end1<end2)
end2=end1;//保证end2始终等于或小于end1
}
if(start1>end1)
break;
if(str[start1]=='B'&&str[end1]=='R')//直接交换
{
tmp=str[start1];
str[start1]=str[end1];
str[end1]=tmp;
}
else if(str[start1]=='G'&&str[end1]=='R')
{
//先交换
tmp=str[start1];
str[start1]=str[end1];
str[end1]=tmp;
while(end2>start2)//然后用end2向前扫描知道遇到第一个不是'G'的字符
{
if(str[end2]!='G')
break;
end2--;
}
if(start2<end2)//若start2<end2,则end2和end1位置的字符交换
{
tmp=str[end2];
str[end2]=str[end1];
str[end1]=tmp;
}
}
else if(str[start1]=='B'&&str[end1]=='G')
{
//先交换
tmp=str[start1];
str[start1]=str[end1];
str[end1]=tmp;
while(start2<end2)//然后用start2向前扫描知道遇到第一个不是'G'的字符
{
if(str[start2]!='G')
break;
start2++;
}
if(start2<end2)//若start2<end2,则start2和start1位置的字符交换
{
tmp=str[start2];
str[start2]=str[start1];
str[start1]=tmp;
}
}
else
{
while(start2<=end2)//分别用start2和end2从前,从后,向后,向前扫描第一个不是'G'的字符
{
if(str[start2]!='G'&&str[end2]!='G')
break;
if(str[start2]=='G')
start2++;
if(str[end2]=='G')
end2--;
}
if(start2==end2&&str[start2]=='R')//若两下标相遇,并且是字符'R',则和start1位置'G'的字符交换
{
tmp=str[start2];
str[start2]=str[start1];
str[start1]=tmp;
}
if(start2==end2&&str[end2]=='B')//若两下标相遇,并且是字符'B',则和end1位置'G'的字符交换
{
tmp=str[end2];
str[end2]=str[end1];
str[end1]=tmp;
}
if(start2<end2)//若两下标相遇,分别交换start1与start2,end1与end2位置的字符
{
tmp=str[end2];
str[end2]=str[end1];
str[end1]=tmp; tmp=str[start2];
str[start2]=str[start1];
str[start1]=tmp;
}
}
if(start2>=end2)//若start2与end2相遇,则扫描结束,保证扫描字符串一遍,因为扫描过程中start2始终在start1后面,end2始终在end1前面,
break;
} }

时间复杂度为O(len),空间复杂度为O(1).

给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。的更多相关文章

  1. 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。

    在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...

  2. HDU 1710 二叉树遍历,输入前、中序求后序

    1.HDU  1710  Binary Tree Traversals 2.链接:http://acm.hust.edu.cn/vjudge/problem/33792 3.总结:记录下根结点,再拆分 ...

  3. 玩透二叉树(Binary-Tree)及前序(先序)、中序、后序【递归和非递归】遍历

    基础预热: 结点的度(Degree):结点的子树个数:树的度:树的所有结点中最大的度数:叶结点(Leaf):度为0的结点:父结点(Parent):有子树的结点是其子树的根节点的父结点:子结点/孩子结点 ...

  4. 有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...

  5. Java实现二叉树先序,中序,后序,层次遍历

    一.以下是我要解析的一个二叉树的模型形状.本文实现了以下方式的遍历: 1.用递归的方法实现了前序.中序.后序的遍历: 2.利用队列的方法实现层次遍历: 3.用堆栈的方法实现前序.中序.后序的遍历. . ...

  6. 给定一个字符串,根据字符出现频率排序--Java实现

    题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...

  7. 给定任意一个字符串,使用 for in 语句来统计字符出现的个数

    //找出字符串中的数字 var str = 'haj123sdk54hask33dkhalsd879'; /*function findNum(str){ var arr = []; var tmp ...

  8. 给定一个字符串,仅由a,b,c 3种小写字母组成。

    package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...

  9. 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length

    // 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba ...

随机推荐

  1. windows下设置/删除Tomcat的开机自启动

    绿色版tomcat在配置好Java环境以后直接运行bin下面的startup.bat就能够正常启动,但是在客户这里很多时候都 需要tomcat开机自动启动.下面简单介绍一如何在windows下面开机自 ...

  2. prime算法求最小生成树(畅通工程再续)

    连着做了四道畅通工程的题,其实都是一个套路,转化为可以求最小生成树的形式求最小生成树即可 这道题需要注意: 1:因为满足路的长度在10到1000之间才能建路,所以不满足条件的路径长度可以初始化为无穷 ...

  3. iReport 4.1 报表制作,子报表,实例解析

    开发使用步骤(iReport 4.1.1) (个人总结,如有问题请留言,另外知道table控件用法的给我留言或者发邮件谢谢.Email:jiazx0107@163.com) 目录 1.      开发 ...

  4. poj 3348 Cows 求凸包面积

    题目链接 大意: 求凸包的面积. #include <iostream> #include <vector> #include <cstdio> #include ...

  5. codeforces 633G. Yash And Trees dfs序+线段树+bitset

    题目链接 G. Yash And Trees time limit per test 4 seconds memory limit per test 512 megabytes input stand ...

  6. call和apply方法的理解

    第一种:直接先来个粟子吧... ; }   var child = {}; console.log(child); //Object() 对象 Parent.call(child); console. ...

  7. mysql-connector-c 安装

    cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/usr/local make make install

  8. 关于 rand() 函数返回值的值域的疑问

    <C语言参考手册>中关于 rand() 函数有如下描述. (1)rand() 函数的原型 int rand(void); (2)连续调用 rand 将返回 0 到 int 类型的最大可表示 ...

  9. RHEL4-Partition Image系统备份(软件版)

    对于BBS,或Apache,PHP等相关网页的程序 备份: 1)/var/www/html目录,里面有PHP所写成的网页.此网页主要功能是从资料库中读取由信件存入的文章,或是使用者选择由网页输入资料时 ...

  10. 解决Windows 程序界面闪烁问题的一些经验

    原帖地址:http://blog.joycode.com/yaodong/archive/2004/11/26/39764.aspx 一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化 ...