Careerup Top 150 Question(1)

4 篇文章 0 订阅
1 篇文章 0 订阅


《Careerup Top 150 Question》是国外的一本面试编程书,里边共有150道常见的题目,书中代码用Java实现,最近尝试自己来实现。


另外,有大牛已经将java代码翻译成了C++代码,对于此系列的文章的较好的设计思路,也会用Java代码进行实现。查看地址:http://hawstein.com/posts/ctci-solutions-contents.html

        言归正传,下面看第一个题目:

         

         Implement an algorithm todetermine if a string has all unique characters. What if you can not useadditional data structures?

        不使用额外的数据结构,实现一个算法用来判断一个字符串是否只有唯一的字符串组成。

 

        首先要考虑构成字符串的字符集多大,是ASCII字符还是只有26个字母,对于不同的字符集处理的办法也不相同。

       以ASCII字符为例,最先想到的办法是初始化一个256bool数组,遍历字符串,对于每一个元素,检查在字符串中是否存在,存在即返回false,不存在继续查找。代码如下

public static boolean isUnique(String str) {
		if (str == null || str.trim().length() == 0) {
			return false;
		}
		str = str.trim();
		boolean[] arr = new boolean[256];

		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);

			// 检查当前字符是否已经存在
			if (arr[c]) {
				return false;
			} else {
				arr[c] = true;
			}
		}

		return true;
	}

不论被检查的字符串多长,空间使用量都是256*2个字节,我们可以通过位运算减少空间的使用量。Int32位组成,对于ASCII256个字符,可以映射到8int元素中。我们规定如下,被8整除的字符使用一个int值,被8除余1的元素使用一个元素,……

代码如下

public static boolean isUnique3(String str)
	{
		if (str == null || str.trim().length() == 0) {
			return false;
		}
		
		str = str.trim();
		
		// 8个元素的int数组可以表示整个ASCII字符集
		int[] arr = new int[8];
		
		for(int i = 0; i < str.length(); i++)
		{
			char c = str.charAt(i);
			
			int index = c / 32;	// 寻找该字符所在的元素
			int offset = c % 32; // 寻找字符在元素的位置
			
			if((arr[index] & ( 1 << offset )) > 0)
			{
				return false;
			}
			else
			{
				arr[index] |= 1 << offset;
			}
		}
		
		return true;
	}

使用位运算后,该算法的空间复杂度维持O(n)不变,空间占用下降为4*8=32个字节。

 

如果字符只涉及到a-z的小写字母,使用位运算只使用一个int值即可。

/**
	 * 默认字符只有小写字母,可以将a-z映射到1-26位,对每个字符进行检查,是否该字符已经存在
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isUnique2(String str) {

		if (str == null || str.trim().length() == 0) {
			return false;
		}

		int checker = 0;

		str = str.trim();

		for (int i = 0; i < str.length(); i++) {
			int c = str.charAt(i) - 'a'; // 获取当前字符应该映射的位数

			// 检查该字符是否存在
			if ((checker & (1 << c)) > 0) {
				return false;
			} else {
				checker |= 1 << c; // 将该字符的对应的位数置为1
			}
		}

		return true;
	}


今天是第一次写该系列的文章,后边要好好坚持下去,加油。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值