给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。
题目:给定一个字符串里面只有"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),且只能遍历一次字符串。的更多相关文章
- 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...
- HDU 1710 二叉树遍历,输入前、中序求后序
1.HDU 1710 Binary Tree Traversals 2.链接:http://acm.hust.edu.cn/vjudge/problem/33792 3.总结:记录下根结点,再拆分 ...
- 玩透二叉树(Binary-Tree)及前序(先序)、中序、后序【递归和非递归】遍历
基础预热: 结点的度(Degree):结点的子树个数:树的度:树的所有结点中最大的度数:叶结点(Leaf):度为0的结点:父结点(Parent):有子树的结点是其子树的根节点的父结点:子结点/孩子结点 ...
- 有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
// ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...
- Java实现二叉树先序,中序,后序,层次遍历
一.以下是我要解析的一个二叉树的模型形状.本文实现了以下方式的遍历: 1.用递归的方法实现了前序.中序.后序的遍历: 2.利用队列的方法实现层次遍历: 3.用堆栈的方法实现前序.中序.后序的遍历. . ...
- 给定一个字符串,根据字符出现频率排序--Java实现
题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...
- 给定任意一个字符串,使用 for in 语句来统计字符出现的个数
//找出字符串中的数字 var str = 'haj123sdk54hask33dkhalsd879'; /*function findNum(str){ var arr = []; var tmp ...
- 给定一个字符串,仅由a,b,c 3种小写字母组成。
package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...
- 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length
// 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba ...
随机推荐
- jacksons转换大小写处理
import com.fasterxml.jackson.databind.ObjectMapper; 1.注意导入的objectMapper包一致 另:jackson的注解大全 https://gi ...
- BZOJ 1406: [AHOI2007]密码箱( 数论 )
(x+1)(x-1) mod N = 0, 枚举N的>N^0.5的约数当作x+1或者x-1... ------------------------------------------------ ...
- Mysql 如何做双机热备和负载均衡 (方法二)
先简要介绍一下mysql双向热备:mysql从3.23.15版本以后提供数据库复制功能.利用该功能可以实现两个数据库同步,主从模式(A->B),互相备份模式(A<=>B)的功能. m ...
- python parse命令行参数
#!/usr/bin/env python import sys def main(argv): for arg in argv: print arg if __name__ == '__main__ ...
- break在switch中的使用例子
/* Name:break在switch中的使用例子 Copyright: By.不懂网络 Author: Yangbin Date:2014年2月21日 03:16:52 Description:以 ...
- lock table
1.在执行lock table语句后,则在执行unlock tables之前,当前会话只能操作当前被锁定的表(包括表别名)2.read锁,其它会话只有读取权限,没有写入权限3.write锁,其它会话只 ...
- PCB外形加工培训教材
一.目录1.外形加工制程介绍2.外形加工机器介绍3.各制程流程介绍3.1锣板制程3.2V-Cut3.3啤板3.4斜边3.5洗板4.环保5.工业安全 1.0 外形加工制程介绍 外形加工包括: 1.1锣板 ...
- [置顶] SpecDD(混合的敏捷方法模型)主要过程概述
敏捷已成为当今使用最广泛的开发方法.有趣的是,敏捷方法的流行性并不是因为它取代了其他开发方法,相反它与这些方法进行了更好地融合.现实世界众多敏捷项目的成功,也证明了敏捷将走向杂化的未来. SpecDD ...
- Codeforces 700A As Fast As Possible(二分答案)
[题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...
- localstroge可以在页面间传递数值;
连接地址为:http://4.suancai.sinaapp.com/localstorg/a.html 原理是,a页面设置了sessionstorge,b页面可以访问到; 并且已关闭浏览器,sest ...