Top 150 Questions - 1.3

1.3 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.

DeleteDuplicate1()函数使用的是递归的方法,当处理到size大小的时候,假设前size-1的字符串已经消除了重复数据(多余的数据替换成了'\0');如果前size-1的字符串中有字符与size处字符相同,则把size处字符替换为'\0';全部处理完后,删除'\0'。这个是最开始想到的方法,觉得有两个问题:1. 使用了系统堆栈O(n),不知道算不算是additional buffer;2. 最后删除'\0'的步骤感觉很多余,不过递归过程肯定不能移动字符串,否则在循环中能处理掉重复数据就好了。在判断字符串时候为空的时候用了str == null,导致空字符串输入时出错。。。

DeleteDuplicate2()函数使用了hash,不过256的数组应该算是additional buffer了吧。

DeleteDuplicate3()函数参照了书中的解法,把整个字符串分成两部分,前面一部分(tail变量之前的字符串)为已经处理过没有重复数据的字符串,后面的字符串为待处理字符串。i,j变量分别用来遍历这两部分字符串。本质上跟递归版本类似,但没想到这里tail变量的作用。

Test Cases书上写了6个,漏掉了2个,思维还不严密难过:1. String does not contain any duplicates, e.g.: abcd; 2. String contains all duplicates, e.g.: aaaa; 3. Null string; 4. Empty string; 5. String with all continuous duplicates, e.g.: aaabbb; 6. String with non-contiguous duplicates, e.g.: abababa

package Question1_3;

public class Question1_3
{
	public static void main(String[] args)
	{
		Question1_3 q = new Question1_3();
		StringBuffer[] strings = 
			{
				new StringBuffer("abcdefg"),
				new StringBuffer("aabbccddeeffgghhiijjkkllmmnn"),
				new StringBuffer("abcdefgabcdefg"),
				new StringBuffer("aaaaaaa"),
				new StringBuffer("t"),
				new StringBuffer("ababababababa"),
				new StringBuffer("12 32 9 ' e.g e' f"),
				new StringBuffer(),
			};
		
		for (StringBuffer str : strings)
		{
			q.DeleteDuplicate1(str);
			System.out.println(str);
		}
	}
	
	public void DeleteDuplicate1(StringBuffer str)
	{
		// can not use str == null to check whether str is empty
		if (str.length() == 0)
			return;
		
		DeleteDuplicate1Helper(str, str.length());
		
		// delete markers
		int index;
		while ((index = str.indexOf("\0")) != -1)
		{
			str.deleteCharAt(index);
		}
	}
	private void DeleteDuplicate1Helper(StringBuffer str, int size)
	{
		if (size == 1)
			return;
		else
		{
			// recursively solve the problem until size == 1
			DeleteDuplicate1Helper(str, size - 1);	
			
			// for every char before str[size-1], check if they are equal. If so, then
			// mark str[size-1] as duplicated.(change it to '\0')
			for (int i = 0; i < size-1; i++)
				if (str.charAt(i) == str.charAt(size - 1))
				{
					str.setCharAt(size - 1, '\0');
					break;
				}
		}
	}
	
	public void DeleteDuplicate2(StringBuffer str)
	{
		if (str.length() == 0 || str.length() == 1)
			return;
		
		boolean[] chars = new boolean[256];
		int i, tail = 0;
		
		for (i = 0; i < str.length(); i++)
		{
			// there is no duplicate at i, so add str[i] to tail.(copy and increment)
			if (chars[str.charAt(i)] == false)
			{
				chars[str.charAt(i)] = true;
				str.setCharAt(tail, str.charAt(i));
				tail++;
			}
		}
		
		str.delete(tail, str.length());
	}
	
	public void DeleteDuplicate3(StringBuffer str)
	{
		if (str.length() == 0 || str.length() == 1)
			return;
		
		int i, j, tail = 1;
		for (i = 1; i < str.length(); i++)
		{
			// check if there is duplicate
			for (j = 0; j < tail; j++)
				if (str.charAt(i) == str.charAt(j))
					break;
			
			// there is no duplicate
			if (j == tail)
			{
				str.setCharAt(tail, str.charAt(i));
				tail++;
			}
		}
		
		str.delete(tail, str.length());
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值