原文:
Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra copy of the array is not.
FOLLOW UP
Write the test cases for this method.
译文:
设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。
进一步地,
为你的程序写测试用例。
package chapter_1_arraysandstring;
import java.util.Scanner;
/**
* 设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。
*
* 假设字符范围为ASCAII
*
* @author LiangGe
*
*/
public class Question_1_3 {
/**
* 每次遍历单词就往前面无重复单词对比,
* position记录无重复单词的最后位置
* 最差情况是数据本身就无重复字符,每次遍历都需要当前字符前所有字符
*
* O(n2 )
*
* @param array
* @return
*/
public static int deleteDuplicate(char array[]) {
int position = 0;
int i, j;
for(i=0; i<array.length; i++) {
for(j=0; j<position; j++) {
if(array[i] == array[j]) {
break;
}
}
if(j == position) {
array[position ++] = array[i];
}
}
return position;
}
/**
* 使用额外标记数组tag记录字符是否已经出现,
* position记录无重复单词的最后位置
* 只需要遍历一遍数组
*
* 0(n)
*
* @param array
* @return
*/
public static int deleteDuplicate2(char array[]) {
int len, position;
boolean tag[] = new boolean[256];
for(int i=0; i<tag.length; i++) {
tag[i] = false;
}
position = 0;
for(int i=0; i<array.length; i++) {
if(!tag[(int)array[i]]) {
array[position ++] = array[i];
tag[(int)array[i]] = true;
}
}
return position;
}
/**
* 如果字符序列只有英文字母a-z,可以使用一个int类型4个字节32位记录字符是否出现
* 只需要扫面一遍
*
* 0(n)
*
* @param array
* @return
*/
public static int deleteDuplicate3(char array[]) {
int position = 0;
int tag = 0;
for(int i=0; i<array.length; i++) {
int now = array[i] - 'a';
// 字符没有出现过
if((tag & (1 << now)) == 0) {
array[position ++] = array[i];
tag |= (1 << now);
}
}
return position;
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String str = scanner.nextLine();
char array[] = str.toCharArray();
int len = deleteDuplicate3(array);
for(int i=0; i<len; i++) {
System.out.print(array[i]);
}
System.out.println();
}
}
}
本文介绍了一种在不使用额外缓存空间的情况下去除字符串中重复字符的算法,并提供了三种不同复杂度的实现方法,包括使用额外标记数组和利用英文字母特性等技巧。

被折叠的 条评论
为什么被折叠?



