程序员面试金典——1.1确定字符互异

程序员面试金典——1.1确定字符互异

2018年4月7日从今天开始正式看《程序员面试金典》

Solution1:

之前一直以为的这类题比较好的一种方法,但貌似还是不太符合题目要求的“不要使用额外的存储结构”,但无论如何先记录下来吧~
使用了额外的存储空间。。。

class Different {
public:
    bool checkDifferent(string iniString) {
        // write code here
        int A[256] = {0};
        for(int i = 0; i < iniString.size(); i++) {
            if(A[iniString[i]] == 0)
                A[iniString[i]]++;
            else if(A[iniString[i]] == 1)
                return false;
        }
        return true;
    }
};

Solution2:

参考网址:https://www.nowcoder.com/profile/6664749/codeBookDetail?submissionId=16328058
看到多数人的答案,我觉得似乎有些不妥。
1)哈希法 首先char类型判断重复,用hash数组最方便,只需要256个bool类型即可,O(n)的时间(其实只要判断前257个就行了O(1),抽屉原理),但是题目要求不能使用额外的存储结构,那么这个方法KO掉。
2)遍历 那么只能用两层for循环遍历,时间复杂度为O(n*n),但是根据抽屉原理,没必要遍历到N,只需要遍历到前257就够了,如果N<257就遍历到N,所以时间复杂度其实为O(1)!!!
3)排序 既然题目要求不能使用额外空间,而参数列表没有const或引用,那么就可以对字符串排序,然后再判断,需要O(nlogn)排序,然后再遍历一遍O(n)。其实也没必要全都排序,只需前257个,同抽屉原理。
4)Partition 基于快速排序的partition,可以边排序边找重复 ,也即是每次partition之后,判断中间key元素与两边元素是否相同,相同则返回false,不同再进行下一轮partition.时间复杂度也是O(nlongn),但要比排序速度快。
综上,其实此题若改为长度为N的整形数组,不用额外空间 ,这题目就Perfect!下面贴出基于partition的代码。

class Different {  
bool quick_check(string &str,int low,int high){
        int first = low,last = high;
        char key = str[first];
        if (low>=high)
            return true;
        while(first<last){
            while(first <last && str[last] >= key)
                last--;           
            str[first] = str[last];
            while(first<last && str[first] <= key)
                first++;
            str[last] = str[first];
        }
        str[first] = key;
        if (first>low && str[first] == str[first-1])
            return false;
        if (first<high && str[first] == str[first+1])
            return false;
        return quick_check(str,low,first-1) && quick_check(str,first+1,high);
    }
public:
    bool checkDifferent(string iniString) {
        // write code here
        return quick_check(iniString,0,iniString.size()-1);
    }
};

5)正则表达式 正则表达式的功能真是很强大,是处理字符串的利器。除了不太容易学之外没什么缺点了。。
这里贴一个java版的正则表达式的代码

public boolean checkDifferent(String iniString) {   
    return !iniString.matches(".*(.)(.*\\1).*");
}

.:代表任意一个字符
.:代表任意一个字符后面有0个或多个字符
(.):选择字符中任意一个字符进行复制 和后面的(.
\1)结合进行判断是否后面存在一个字符与它相同
(.)(.\1):匹配案例 aa(即首尾相同的abcsa)
(.)(.\1).:匹配案例 aa
.(.)(.\1):匹配案例 aa
.(.)(.\1).:匹配案例 aa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值