Java算法面试题(004) 实现一个算法来确定一个字符串是否具有所有唯一的字符

问题分析

你应该首先询问面试官,需要处理的字符串是一个ASCII字符串还是一个Unicode字符串。提出这个问题将展现你对细节的考虑和你坚实的计算机科学基础。为了简单起见,我们将假设字符串为ASCII类型。
一种解决方案是创建一个布尔值数组,其中位于索引i的标志指示字符i是否包含在字符串中。你第二次看到这个标识,你可以立即返回false。如果字符串长度超过了唯一字符的数量,我们也可以立即返回false。

算法

具体的算法实现如下:

	public boolean isUniqueChars(String str) {
		if (str.length() > 128) {
			return false;
		}

		boolean[] charSet = new boolean[128];

		for (int i = 0; i < str.length(); i++) {
			int val = str.charAt(i);
			if (charSet[val]) { // already found this char in string
				return false;
			}

			charSet[val] = true;
		}

		return true;
	}

这个代码的时间复杂度是O(n),其中n是字符串的长度。

我们可以通过使用位向量来将我们的空间使用减少八倍。我们将假设,在下面的代码中,该字符串只使用小写字母a到z。

	/*
	 * We can reduce our space usage by a factor of eight by using a bit vector.
	 * We will assume, in the below code, that the string only uses the
	 * lowercase letters a through z. This will allow us to use just a single
	 * int.
	 */
	public boolean isUniqueChars(String str) {
		int checker = 0;
		for (int i = 0; i < str.length(); i++) {
			int val = str.charAt(i) - 'a';

			if ((checker & (1 << val)) > 0) {
				return false;
			}

			checker |= (1 << val);
		}
		return true;
	}

进一步的问题

上面的算法,个人认为都是比较典型的以空间换时间的思路。如果我们不能使用额外的数据结构,可以考虑下面的算法实现:
1. 将字符串的每个字符与字符串的每个其他字符进行比较。这将花费O(n2)时间和O(1)空间。
2. 如果允许修改输入字符串,我们可以在O(n log(n))时间内对字符串进行排序,然后再检查相邻字符串是否相同。

算法拓展

接下来,我们来拓展一下本文中使用的算法,来检查两个字符串是否具有相同的字符数(permutation)。我们也可以使用排列的定义 – 具有相同字符数的两个词来实现这个算法。我们只是迭代这个代码,计算每个字符出现的次数。之后,我们比较两个数组。

	public boolean permutation(String s, String t) {
		if (s.length() != t.length()) {
			return false;
		}

		int[] letters = new int[128];

		char[] s_array = s.toCharArray();
		for (char c : s_array) {
			letters[c]++;
		}

		for (int i = 0; i < t.length(); i++) {
			int c = (int) toString().charAt(i);
			letters[c]--;
			
			if (letters[c] < 0) {
				return false;
			}
		}
		
		return true;
	}
    原文作者:刘近光
    原文地址: https://blog.csdn.net/jinguangliu/article/details/78667231
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞