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

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

C ++代码如下:

  1. #include<iostream>
  2. #include<cstring>
  3. using namespace std;
  4. const int MAXLEN=100;//字符串的最大长度
  5. void Set_RGB(char *str);//位置调整函数,借助了快排的partition函数思想
  6. int main()
  7. {
  8. char str[MAXLEN+1];
  9. cin>>str;//输入只包含'R','G','B'的字符串
  10. Set_RGB(str);
  11. cout<<str<<endl;//输出调整过的字符串
  12. return 0;
  13. }
  14. void Set_RGB(char *str)
  15. {
  16. if(str==NULL)
  17. return;
  18. int len=strlen(str);
  19. int start1,end1,start2,end2;
  20. char tmp;
  21. start1=start2=0;
  22. end1=end2=len-1;
  23. while(true)
  24. {
  25. while(str[start1]=='R'&&start1<=end1)
  26. {
  27. start1++;
  28. if(start1>start2)
  29. start2=start1;//保证start2始终等于或大于start1
  30. }
  31. while(str[end1]=='B')
  32. {
  33. end1--;
  34. if(end1<end2)
  35. end2=end1;//保证end2始终等于或小于end1
  36. }
  37. if(start1>end1)
  38. break;
  39. if(str[start1]=='B'&&str[end1]=='R')//直接交换
  40. {
  41. tmp=str[start1];
  42. str[start1]=str[end1];
  43. str[end1]=tmp;
  44. }
  45. else if(str[start1]=='G'&&str[end1]=='R')
  46. {
  47. //先交换
  48. tmp=str[start1];
  49. str[start1]=str[end1];
  50. str[end1]=tmp;
  51. while(end2>start2)//然后用end2向前扫描知道遇到第一个不是'G'的字符
  52. {
  53. if(str[end2]!='G')
  54. break;
  55. end2--;
  56. }
  57. if(start2<end2)//若start2<end2,则end2和end1位置的字符交换
  58. {
  59. tmp=str[end2];
  60. str[end2]=str[end1];
  61. str[end1]=tmp;
  62. }
  63. }
  64. else if(str[start1]=='B'&&str[end1]=='G')
  65. {
  66. //先交换
  67. tmp=str[start1];
  68. str[start1]=str[end1];
  69. str[end1]=tmp;
  70. while(start2<end2)//然后用start2向前扫描知道遇到第一个不是'G'的字符
  71. {
  72. if(str[start2]!='G')
  73. break;
  74. start2++;
  75. }
  76. if(start2<end2)//若start2<end2,则start2和start1位置的字符交换
  77. {
  78. tmp=str[start2];
  79. str[start2]=str[start1];
  80. str[start1]=tmp;
  81. }
  82. }
  83. else
  84. {
  85. while(start2<=end2)//分别用start2和end2从前,从后,向后,向前扫描第一个不是'G'的字符
  86. {
  87. if(str[start2]!='G'&&str[end2]!='G')
  88. break;
  89. if(str[start2]=='G')
  90. start2++;
  91. if(str[end2]=='G')
  92. end2--;
  93. }
  94. if(start2==end2&&str[start2]=='R')//若两下标相遇,并且是字符'R',则和start1位置'G'的字符交换
  95. {
  96. tmp=str[start2];
  97. str[start2]=str[start1];
  98. str[start1]=tmp;
  99. }
  100. if(start2==end2&&str[end2]=='B')//若两下标相遇,并且是字符'B',则和end1位置'G'的字符交换
  101. {
  102. tmp=str[end2];
  103. str[end2]=str[end1];
  104. str[end1]=tmp;
  105. }
  106. if(start2<end2)//若两下标相遇,分别交换start1与start2,end1与end2位置的字符
  107. {
  108. tmp=str[end2];
  109. str[end2]=str[end1];
  110. str[end1]=tmp;
  111.  
  112. tmp=str[start2];
  113. str[start2]=str[start1];
  114. str[start1]=tmp;
  115. }
  116. }
  117. if(start2>=end2)//若start2与end2相遇,则扫描结束,保证扫描字符串一遍,因为扫描过程中start2始终在start1后面,end2始终在end1前面,
  118. break;
  119. }
  120.  
  121. }

时间复杂度为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. fork进程函数总结

    学习链接: http://blog.csdn.net/jason314/article/details/5640969 http://coolshell.cn/articles/7965.html 搜 ...

  2. [C#参考]UI和线程(一)

    Windows是一个多任务的系统,如果你使用的是windows 2000及其以上版本,你可以通过任务管理器查看当前系统运行的程序和进程. 什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指包 ...

  3. 获取select赋值

    <select class="sel-ul-add" id="xuanzhe"> <option>A</option> &l ...

  4. Models——英语学习小技巧之四

    Models  are very important, here model means role model, is kind of like a hero. It's  someone that ...

  5. <正向/反向>最大匹配算法(Java)

    算法描述(正向): 给定最大词长n,待分词文本str,指针f=0,词典dic文档 1 取子串sub=str(f,f+n) 2 如果(遍历dic,有匹配sub) f++; 3 否则 n--; 4 注意: ...

  6. 【LeetCode题意分析&解答】42. Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  7. 树的判断(poj nyoj hduoj)

    题目: http://ac.jobdu.com/problem.php?pid=1481 http://acm.nyist.net/JudgeOnline/problem.php?pid=129 ht ...

  8. Linux例行工作crontab

    第一步编辑要定时执行的脚本: myScript.sh myScript.sh的内容为:touch /root/`date +%F' '%T`.txt 为myScript.sh增加可执行权限:chmod ...

  9. Effective C++学习笔记——构造/析构/拷贝运算

    条款9:决不再构造和析构过程中调用virtual函数,包括通过函数间接调用virtual函数. 应用:想在一个继承体系中,一个derived class被创建时,某个调用(例如生成相应的日志log)会 ...

  10. ICT测试原理

    在线测试,ICT,In-Circuit Test,是通过对在线元器件的电性能及电气连接进行测试来检查生产制造缺陷及元器件不良的一种标准测试手段.它主要检查在线的单个元器件以及各电路网络的开.短路情况, ...