面试题 01.01. 判定字符是否唯一
面试题 01.01. 判定字符是否唯一
实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
示例 1:
输入: s = "leetcode"
输出: false
示例 2:
输入: s = "abc"
输出: true
解法1:哈希表计数
思路:
遍历字符串,利用哈希表存储每个字符出现的次数,当当前遍历到的字符已经出现过,直接返回false;若遍历完整个字符串且未发现重复字符,则返回true。
实现细节:
普通的map内部用红黑树实现,保证有序,但空间占用率高。
unordered_map内部实现了哈希表,查找速度很快,均为O(1)复杂度,但建立比较耗费时间。
对于本题,不需要保证内部有序,所以使用unordered_map即可。
class Solution {
public:
bool isUnique(string s) {
unordered_map<char, int> mp;
for(char c : s) {
if(mp[c] > 0) {
return false;
} else {
mp[c] = 1;
}
}
return true;
}
};
复杂度分析:
假设字符串长度为N,则遍历字符串时间复杂度为O(N),每个字符查找复杂度为O(1),故总时间复杂度为O(N),时间消耗击败100%,故时间复杂度已达到最优;
利用哈希表存储,空间复杂度为O(N),本解法内存消耗只击败了5%,说明可以优化。
解法2:位运算
思路:
要求不使用额外的数据结构,且根据解法1可知,存在空间复杂度O(1)的解法。解法1考虑了字符串中出现的字符数,现在我们反过来考虑每个字符出现的次数。
由于一共有26种字符,所以我们用一个0-1串记录所有字符出现的次数,某一个字符出现过,则将其所在位的值置1,若再次出现,且该位已经为1,则返回false;
实现细节:
将26个字符转换为0-25的数字,并分别对应0-25位,设该0-1串为x。
把x的第k位置1: x = x | (1 << k) 同理,判断x的第k位是否为1,用&运算即可。
代码:
class Solution {
public:
bool isUnique(string s) {
int x = 0;
for(char c : s) {
if(x & (1 << (c - 'a'))) { // c - 'a':将字符转换为0-25的数字
return false;
} else {
x |= 1 << (c - 'a');
}
}
return true;
}
};
复杂度分析:
与解法1相同,遍历字符串时间复杂度为O(N),每个字符的位运算复杂度为O(1),故总时间复杂度为O(N);
只利用了一个变量x,空间复杂度为O(1),为最优。
因上求缘,果上努力~~~~ 作者:图神经网络,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13618222.html