原文:
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();
}
}
}