老张
算法工程师
最近遇到一个有趣的算法问题,类似于字符消消乐游戏,需要消除字符串中相邻的重复字符。这个问题看似简单,但实现起来却有不少细节需要考虑。本文将详细介绍这个问题的解法,并提供完整的Java实现代码。
给定一个字符串,消除其中所有相邻的重复字符。类似于消消乐游戏,但只需要两个相同的相邻字符即可消除。例如:
abbbaadeffc → decabbbcdeffc → acdec消除规则:
这个问题可以使用递归或栈来解决。本文采用递归方法,主要思路如下:
import java.util.ArrayList;
import java.util.List;
public class StringElimination {
public static void main(String[] args) {
String originalStr = "abbbaadeffc";
// String originalStr = "abbbcdeffc";
List<String> originalCharsList = new ArrayList<>();
// 将字符串转换为字符列表
for (int k = 0; k < originalStr.length(); k++) {
originalCharsList.add(String.valueOf(originalStr.charAt(k)));
}
eliminateDuplicates(originalCharsList);
}
/**
* 消除相邻重复字符的主方法
* @param input 输入的字符列表
*/
public static void eliminateDuplicates(List<String> input) {
if (input == null || input.isEmpty()) {
return;
}
int startIndex = 0;
int repeatTimes = 0;
String currentChar = "";
for (int i = 0; i < input.size(); i++) {
if (currentChar.isEmpty()) {
currentChar = input.get(i);
startIndex = i;
repeatTimes = 1;
continue;
}
if (currentChar.equals(input.get(i))) {
repeatTimes++;
} else {
if (repeatTimes > 1) {
input = removeDuplicates(input, startIndex, repeatTimes);
eliminateDuplicates(input);
return;
}
currentChar = input.get(i);
startIndex = i;
repeatTimes = 1;
}
}
if (repeatTimes > 1) {
eliminateDuplicates(removeDuplicates(input, startIndex, repeatTimes));
} else {
// 输出最终结果
StringBuilder result = new StringBuilder();
for (String item : input) {
result.append(item);
}
System.out.println(result.toString());
}
}
/**
* 移除指定范围内的重复字符
* @param input 输入列表
* @param startIndex 开始索引
* @param repeatTimes 重复次数
* @return 处理后的列表
*/
private static List<String> removeDuplicates(List<String> input, int startIndex, int repeatTimes) {
List<String> result = new ArrayList<>();
for (int i = 0; i < input.size(); i++) {
if (i < startIndex || i >= startIndex + repeatTimes) {
result.add(input.get(i));
}
}
return result;
}
} 最坏情况下,每次只能消除一对字符,时间复杂度为O(n²)。平均情况下,时间复杂度接近O(n)。
使用了额外的列表存储字符,空间复杂度为O(n)。
可以使用栈来优化这个算法:
public static String eliminateWithStack(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (!stack.isEmpty() && stack.peek() == c) {
stack.pop();
} else {
stack.push(c);
}
}
StringBuilder sb = new StringBuilder();
for (char c : stack) {
sb.append(c);
}
return sb.toString();
} | 输入 | 输出 | 说明 |
|---|---|---|
abbbaadeffc | dec | 消除bbb、aaa、ff |
abbbcdeffc | acdec | 消除bbb、ff |
aabbccdd | "" | 全部消除 |
abcde | abcde | 无重复字符 |
本文介绍了消除相邻重复字符的算法,关键点包括:
这个问题看似简单,但能很好地考察对字符串处理、递归和栈的理解。希望本文对你有所帮助,欢迎留言讨论更好的解决方案!