赞
踩
三色球问题
RGB分别代表红色,绿色,蓝色球。
输入 给定一串字符串 如“RRRRGGGGGGBGGBBBB”
返回 G 5 6 7 8 9 10
R 1 2 3 4
B 14 15 16 17
G 12 13
解释:第一行 先输出 颜色相同 连续的 最长球串,如上述字符串中 显然G那段最长,从第5个开始,到第10个结束,所以第一行输出 G 5 6 7 8 9 10
第二行,在第一行奖G输出之后,就要从字符串中删除G,原来的字符串被分为两个 “RRRR”和“BGGBBBB”但是仍然要保持在原来串中的先后次序。此时最长的就是RRRR和BBBB,规则:碰到多段等长的球串 输出最左边的 因此 输出 R 1 2 3 4
第三行,同理 删除第二行输出的R,原串变成 BGGBBBB,此时最长显然为B那段 因此输出 B 14 15 16 17,为什么不是B 4 5 6 7 呢,
规则:虽然前面删除了已经输出的串,但是不管删多少后面输出时,仍然按照 球在原来字符串中位置信息输出。
就是这样。
package other; import java.util.HashMap; /** * @author lzm * @create 2020- 04- 06- 15:56 * 题目:给一个字符串 由RGB(红绿蓝)3种字母组成 * 1.找出串中最长的相同子串,输出字母以及所在位置,然后剔除(如有多个相同拿最左的子串) * 2.将剩余部分按序连接,如果只有一个字母则结束游戏,否则返回第一步 * 注意每次输出的位置为原始串中的位置 * 例: * RBBGGR * B 2 3 * G 4 5 * R 1 6 */ public class Test2 { public static void main(String[] args) { Test2 test2=new Test2(); String s="RRGGGBGG"; test2.RGB(s); } public void RGB(String s) { int rlength=0,glength=0,blength=0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i)=='R') rlength++; if (s.charAt(i)=='G') glength++; if (s.charAt(i)=='B') blength++; } //存储R G B各个位置 int[] red=new int[rlength]; int[] green=new int[glength]; int[] blue=new int[blength]; int r=0,g=0,b=0; String copy=new String(s); for (int i = 0; i < s.length(); i++) { if (s.charAt(i)=='R') { red[r]=i; r++; } if (s.charAt(i)=='G') { green[g]=i; g++; } if (s.charAt(i)=='B') { blue[b]=i; b++; } } while (s.length()>0) { //找出单轮的最大连续个数 int max=1; int start=0,end=0; for (int i = 0; i < s.length()-1; i++) { int count = 1; int p=i; while ( p<s.length()-1&&s.charAt(p) == s.charAt(p + 1) ) { count++; p++; } if (count > max) { start = i; max=count; end=start+max-1; } } char c = s.charAt(start); //a是前面有几个和自己相同的字符 int a= findCharNumBeforeStart(start,c, s); System.out.print(c); for (int j = 0; j <max ; j++) { int location=out(j,a,c,red,green,blue)+1; System.out.print(location); } String substring = s.substring(0, start); String substring1 = s.substring(end+1, s.length()); s=substring+substring1; } } //a是删减的字符串s中最大连续字符的位置,c是返回的R,G,B字符,count是前面被删除的个数 private int out(int j,int a, char c, int[] red, int[] green, int[] blue) { int count=0; if (c=='R'){ while (red[a+j+count]==-1) { count++; } int location=red[a+j+count]; red[a+j+count]=-1; return location; } if (c=='G'){ while (green[a+j+count]==-1) { count++; } int location=green[a+j+count]; green[a+j+count]=-1; return location; } if (c=='B'){ while (blue[a+j+count]==-1) { count++; } int location=blue[a+j+count]; blue[a+j+count]=-1; return location; } return -1; } //查找前面有几个和自己相同的字符 private int findCharNumBeforeStart(int start,char c,String s) { int count=0; for (int i = 0; i < start; i++) { if (s.charAt(i)==c) { count++; } } return count; } }
当s=“RRRRGGGGGGBGGBBBB”时
这道题我感觉还是还是有难度的,考虑的条件有点多,代码应该没啥问题,就是时间复杂度度会差点,就只有这水平了
优化下代码
主要是排序排出来,考虑好边界就行
res = res.stream().sorted(new Comparator<List<Integer>>() {
@Override
public int compare(List<Integer> o1, List<Integer> o2) {
if (o1.get(0).equals(o2.get(0))) {
//count相同 起始位置单调递增
return o1.get(1) - o2.get(1);
} else {
//单调递减
return o2.get(0) - o1.get(0);
}
}
}).collect(Collectors.toList());
package com.lzm.Group3; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; /** * @Description: TODO * @author: lzm * @date: 2021年09月06日 16:00 */ public class Test5 { public static void main(String[] args) { Test5 test5 = new Test5(); String s = "RRRRGGGGGGBGGBBBB"; List<String> res = test5.getRgb(s); for (int i = 0; i < res.size(); i++) { System.out.println(res.get(i)); } } private List<String> getRgb(String s) { if (s.length() == 0) { return new ArrayList<>(); } //定义一个数组记录是否已使用 boolean[] isUse = new boolean[s.length()]; //定义一个list[4] 0:count 1:start 2:end 3:颜色 0:R 1:G 2:B Character[] color = {'R', 'G', 'B'}; List<List<Integer>> res = new ArrayList<List<Integer>>(); int start = 0; int end = 0; int length = s.length(); List<Integer> list = new ArrayList<>(); Character character = new Character(s.charAt(0)); while (end < length) { if (s.charAt(end) == character) { end++; } else { //遍历数组将大小 start end 颜色注入res list.add(end - start + 1); list.add(start); list.add(end); int index = getColorIndex(character); list.add(index); res.add(list); //重新写start start = end; end = start; character = s.charAt(end); list = new ArrayList<>(); } } list.add(end - start); list.add(start); list.add(end); int index = getColorIndex(character); list.add(index); res.add(list); res = res.stream().sorted(new Comparator<List<Integer>>() { @Override public int compare(List<Integer> o1, List<Integer> o2) { if (o1.get(0).equals(o2.get(0))) { //count相同 起始位置单调递增 return o1.get(1) - o2.get(1); } else { //单调递减 return o2.get(0) - o1.get(0); } } }).collect(Collectors.toList()); //数组队列 List<String> rgbString = new ArrayList<>(); for (int i = 0; i < res.size(); i++) { List<Integer> colorList = res.get(i); //得到颜色 Integer integer = colorList.get(3); Character colorCharacter = color[integer]; //开始 结束位置 Integer begin = colorList.get(1); Integer end1 = colorList.get(2); //输出颜色字符串 StringBuilder outColorString = new StringBuilder(); outColorString.append(colorCharacter).append(" "); for (int j = begin+1; j <= end1; j++) { outColorString.append(j).append(" "); } rgbString.add(outColorString.toString()); } return rgbString; } private int getColorIndex(Character character) { Character[] color = {'R', 'G', 'B'}; for (int i = 0; i < color.length; i++) { if (color[i].equals(character)) { return i; } } return -1; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。