面试题 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),为最优。

 

posted @ 2020-09-05 15:26  图神经网络  阅读(98)  评论(0编辑  收藏  举报
Live2D