题目描述:
有 n 个人排成了一行队列,每个人都有一个站立的方向:面向左或面向右。由于这 n 个人中每个人都很讨厌其他的人,所以当两个人面对面站立时,他们会发生争吵,然后其中一个人就会被踢出队列,谁被踢出队列都是有可能的。
我们用字符 L 来表示一个面向左站立的人,用字符 R 来表示一个面向右站立的人,那么这个队列可以用一个字符串描述。比如 RLLR 就表示一个四个人的队列,其中第一个人和第二个人是面对面站立的。他们发生争吵后队列可能会变成 LLR,也可能变成 RLR;若变成 RLR,则第一个人与第二个人还会发生争吵,队列会进一步变成 LR 或者 RR。
若在某个时刻同时可能有很多的争吵会发生时,接下来只会发生其中的一个,且任意一个都是有可能发生的。
你想知道经过一系列的争吵后,这个队列最少会剩下多少人?
输入
第一行包含一个有字符 L 和 R 构成的字符串。1 ≤字符串长度≤ 10^5
样例输入
LRRLRL
样例输出
2
Hint
一种可能的变化情况是:LRRLRL -> LRLRL -> LRRL -> LRL -> LR
思路:
见代码中注释,题目要求最少剩余人数,故不考虑很多人同时吵架等情形,只考虑最小值情形
代码:
import java.util.Scanner;
/**
* 科大讯飞“吵架”笔试题解析
*
* Created by [email protected] since 2018年9月9日 下午7:14:52.
*/
public class Quarrel {
public static void main(String[] args) {
Quarrel quarrel = new Quarrel();
Scanner scanner = new Scanner(System.in);
String str = scanner.next("^[LR]{1,100000}$"); //利用正则表达式校验输入的字符串
while (str.indexOf("RL") > -1) { //字符串第一次出现RL的位置
str = quarrel.remain(str); //字符串中出现RL时一个字符
}
System.out.println("Result: " + str + ", length: " + str.length());
scanner.close();
}
/**
* 剩余字符串
* <li>两个字符的情形有LR/RL两种
* <li>两个以上的字符串中只有RL组合时会有吵架发生
* <ul>
* <li>若RL前面一个是R则删除当前的R
* <li>若RL前面一个是L则删除后面的L,因为当前的R还有可能和后面产生的L组合在一起
* </ul>
*/
public String remain(String src) {
int length = src.length();
if (length == 2 && src.equals("RL")) {
return new String(removeCharAt(1, src));
}
if (length > 2) {
int index = src.indexOf("RL");
if (index == 0) {
return new String(removeCharAt(index + 1, src));
}
if (index >= 1) {
if (src.charAt(index - 1) == 'R') {
return new String(removeCharAt(index, src));
} else {
return new String(removeCharAt(index + 1, src));
}
}
}
return src;
}
/**
* 删除字符串中位于index的字符
* @param index 0~src.length()
*/
public String removeCharAt(int index, String src) {
int newLength = src.length() - 1;
char[] result = new char[newLength];
char[] data = src.toCharArray();
for (int i = 0; i < newLength; i++) {
if (i < index) {
result[i] = data[i];
} else {
result[i] = data[i + 1];
}
}
return new String(result);
}
}
转载请注明出处即可