题目:给定一个字符串里面只有"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. 原生js封装table表格操作,获取任意行列td,任意单行单列方法

    V1.001更新增加findTable-min.js 本次更新,优化了代码性能方面,增加了部分新功能,可以获取多个table表格批量操作. 考虑到本人后面的项目中可能涉及到大量的表格操作,提前先封了 ...

  2. 一个人的旅行(用小技巧转化为dijkstra算法)

    注意: 1:因为两点之间可能有多条路,所以更新路径长度的时候做一次判断 if(time < mat[a][b]) mat[a][b] = mat[b][a] = time; 2:因为主函数中的数 ...

  3. A - 数塔

    A - 数塔 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  4. 搭建Hadoop集群 (三)

    通过 搭建Hadoop集群 (二), 我们已经可以顺利运行自带的wordcount程序. 下面学习如何创建自己的Java应用, 放到Hadoop集群上运行, 并且可以通过debug来调试. 有多少种D ...

  5. 利用merge存储引擎来实现分表

    我觉得这种方法比较适合,那些没有事先考虑,而已经出现了得,数据查询慢的情况.这个时候如果要把已有的大数据量表分开比较痛苦,最痛苦的事就是改代码,因为程序里面的sql语句已经写好了,现在一张表要分成几十 ...

  6. less 工具

    less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...

  7. 如何创建一个简单的struts2程序

    如何创建一个简单的Struts2程序 “计应134(实验班) 凌豪” 1.创建一个新的Web项目test(File->new->Web Project) 2.Struts2框架的核心配置文 ...

  8. SQL 建表 插数据

    CREATE TABLE `article` ( `id` INT() NOT NULL PRIMARY KEY auto_increment, `title` CHAR() NOT NULL, `c ...

  9. C语言迭代求解

    date : 2013/8/12           desinger :pengxiaoen 今天看  国外电子信息科学经典教材系列   <电子电路分析与设计> 电子工业出版社的 的19 ...

  10. VS插件

    VS插件 背景 前些天去考科目二,感觉经历了一场不是高考却胜似高考的考试(10年前的5分之差, 还是难以释怀)!    一行八人,就我学的时间最少(4天,8人一辆车),教练都觉得我肯定还得再来一次! ...