程序员面试金典 1.1

买了书之后发现配书网站上不去,然后就吃灰了,今天偶然发现leetcode可刷。

Is Unique:实现一个算法,判断一个字符串中所有的字符是否都不同。如果不能使用任何额外数据结构又该怎么做呢?

首先你应该问面试官:字符串是ASCII的还是Unicode的?这个问题可以展示出你有很强的计算机科学素养。为了简单这里假设是ASCII的。

一个朴素的解法是创建一个bool类型的数组,元素i表示字符i是否出现在字符串中,当第2次读取到这个字符时,直接返回false即可。

推广一下,如果字符串的长度超过了字符表的长度,就可以直接返回false了,因为你不可能从128ASCII字符中选出不一样的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)的时间将字符串进行排序,然后判断相邻的字符串是否相同即可

这两种解法在某些方面可能不是最好的,但是在题目有一些限制时还是可取的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值