买了书之后发现配书网站上不去,然后就吃灰了,今天偶然发现leetcode可刷。
Is Unique:实现一个算法,判断一个字符串中所有的字符是否都不同。如果不能使用任何额外数据结构又该怎么做呢?
首先你应该问面试官:字符串是ASCII的还是Unicode的?这个问题可以展示出你有很强的计算机科学素养。为了简单这里假设是ASCII的。
一个朴素的解法是创建一个bool类型的数组,元素i表示字符i是否出现在字符串中,当第2次读取到这个字符时,直接返回false即可。
推广一下,如果字符串的长度超过了字符表的长度,就可以直接返回false了,因为你不可能从128个ASCII字符中选出不一样的280个组成一个字符串。
class Solution {
public:
bool isUnique(string astr) {
if(astr.size() > 128) return false;
bool bSet[128] = {false};
for(size_t i = 0; i < astr.size(); i++)
{
if(bSet[astr[i]]) return false;
else bSet[astr[i]] = true;
}
return true;
}
};
时间复杂度为O(n),空间复杂度为O(1)。当然也可以说时间复杂度是O(1),因为当长度大于128时就不会执行for循环了。如果把字符表的大小设置为c,那么空间复杂度为O(c),时间复杂度为O(min(c, n))。
更进一步,可以通过使用位向量来将存储空间缩小为1 / 8。假设字符表只有小写字母a ~ z,那么使用int保存位向量就可以了。
class Solution {
public:
bool isUnique(string astr) {
int vec = 0;
for(size_t i = 0 ; i < astr.size(); i++)
{
int ls = astr[i] - 'a';
if((vec & (1 << ls)) != 0) return false;
else vec |= (1 << ls);
}
return true;
}
};
如果不能使用额外的数据结构,可以考虑下面的办法:
- 将字符两两进行比较,时间复杂度为
O(n ^ 2),空间复杂度为O(1) - 如果可以修改原始字符串,可以用
O(nlogn)的时间将字符串进行排序,然后判断相邻的字符串是否相同即可
这两种解法在某些方面可能不是最好的,但是在题目有一些限制时还是可取的。
1090

被折叠的 条评论
为什么被折叠?



