给定一个字符串里面只有"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 ...
随机推荐
- SQL2008 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。
'OFFSET' 附近有语法错误.在 FETCH 语句中选项 NEXT 的用法无效. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出 ...
- sizeof()的用法
机器平台:X86_64 处理器 操作系统:Red Hat 4.1.2-14 编译器: gcc version 4.1.2 20070626 Size of char is: ...
- leetcode 60. Permutation Sequence(康托展开)
描述: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...
- Anndroid 开发架构读书笔记
市面上大部分应用不外乎就是颠过来倒过去地做以下这些事情: --------------- --------------- --------------- --------------- | | | | ...
- java_httpservice
http://blog.csdn.net/maosijunzi/article/details/41045181
- 【STM32学习笔记1】基于固件库的STM32_MDK工程模版
文章包含STM32固件库介绍和工程模板搭建两方面内容. 一.STM32固件库介绍 要建立工程模板,首先要对STM32的固件库有所了解.STM32的固件可以从ST官网下载,网址为:http://www. ...
- semver语义化版本号
semver语义化版本号 语义化版本号各位置的含义 版本号:X.Y.Z X: 代表发生了不兼容的API改变 Y: 代表向后兼容的功能性变化 Z: 代表向后兼容bug fixes 语义化版本号示例 1. ...
- delphi如何获得当前操作系统语言环境
function GetWindowsLanguage: string; var WinLanguage: ..] of char; begin VerLanguageName(GetSystemDe ...
- C# WinForm判断Win7下是否是管理员身份运行
原文:C# WinForm判断Win7下是否是管理员身份运行 如果程序不是以管理员身份运行,操作本地文件会提示:System.UnauthorizedAccessException异常 Vista 和 ...
- (92) Is there a better crawler than Scrapy? - Quora
(92) Is there a better crawler than Scrapy? - Quora Is there a better crawler than Scrapy?Edit