问题陈述是以递归方式删除字符串中的重复项。 例如:abcddaacg - > abccg-> ABG
现在我实施的算法是:
保持2个指针(i和j)。我总是<学家str [j]总是元素str [i]比较删除重复项。因此,当j = 6且i = 5时,我用' \ 0'替换它们。然后我将j更新为7(c)。然后当j = 4且i = 3时(两者都是d,j得到更新导致str [4]!= str [6],因此j = i,变成j = 4)我们将它们更新为' \ 0'
当我将j更新为7时,我的问题是下一步。为此,我必须搜索下一个不是' \ 0'的字符。这就是使它成为O(n ^ 2)实现的原因。我怎样才能做得更好? O(n)
以下是代码:
static void remDups (String input) {
char [] str = input.toCharArray();
int j = input.length()-1;
int i = input.length()-2;
while (i >= 0){
if (str[i] == str[j]) {
str[i] = '\0';
str[j] = '\0';
j++;
while (str[j] == '\0' && j < str.length) {
j++;
}
} else {
j = i;
}
i--;
}
i = 0;
while (i < input.length()) {
if (str[i] != '\0')
System.out.print(str[i]);
i++;
}
}
答案 0 :(得分:0)
您的算法效率低下的原因在于您使用的数据结构(以及方法)会留下空白区域,而这些空白区域曾经被移除,这使得解决这些问题变得非常昂贵。我可以想到一个更有效的算法,它使用你的方法,但更好的数据结构,我也可以想到一个使用不同方法的更有效的算法。
这就像家庭作业一样,所以我宁愿你自己找到答案而不是直接给你答案,但我鼓励你弄清楚我提到的两种算法(不同的数据结构)但是算法和算法不同。如果您需要提示,请在评论中回复,我将与您合作实现目标......
编辑:我刚刚看到你的评论说匹配是从右到左,所以我的替代算法不会起作用。但是,如果允许贪婪的从左到右的比赛,我鼓励你试着弄明白它会是什么。编辑2:此算法实际上将使用从右到左的匹配,您只需要在字符串中从右向左迭代。
答案 1 :(得分:0)
这是一个使用stack
并删除char[]
上的相邻重复项的迭代解决方案,因为它们更容易使用,因为String
对象是不可变的。
每次迭代:
使用布尔标志来跟踪是否需要删除任何相邻的重复项。
将没有相等邻接的元素推入堆栈。
如果我们找到相等的邻接,在它们相等的情况下递增计数器(因为你可能有两个以上相等的邻居)更新标志,说明需要删除邻接副本
否则我们就完成了
如果该标志被激活,我们用存储在堆栈中的非重复覆盖我们的char[]
并重复循环直到没有删除重复。
以下是代码:
static char[] removeAdjDups(char[] data) {
if (data == null) {
return null;
}
Stack<Character> stack = new Stack<Character>();
boolean removal = true; // flag keeping track if any dups were removed
char[] temp;
while (removal) {
/* set removal to false */
removal = false;
/* push elements that don't have equal adjacents onto the stack */
for (int i = 1; i < data.length; i++) {
if (data[i - 1] != data[i]) {
stack.push(data[i - 1]);
} else {
while (i < data.length && data[i - 1] == data[i]) {
i++;
}
/* if we found equal adjacents, activate the removal flag */
removal = true;
}
if (i == data.length - 1) {
stack.push(data[i]);
}
}
/* if dups were removed
store the array with removed adjacent dups into original data */
if (removal) {
temp = new char[stack.size()];
for (int i = temp.length - 1; i >= 0; i--) {
temp[i] = stack.pop();
}
data = temp;
}
}
return data;
}
public static void main(String[] args) {
String str = "abcddaacg";
System.out.println(removeAdjDups(str.toCharArray()));
}
输出:
abg