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

来源:互联网 发布:微信无法连接网络 编辑:程序博客网 时间:2024/05/16 11:36

问题分析

你应该首先询问面试官,需要处理的字符串是一个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 stringreturn 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;}

阅读全文
0 0
原创粉丝点击