题目
题解
通常一下就能想到的是用一个数组,记录每个字符出现的次数,再遍历,有大于1的就是false。
题目要求不能用额外的数据结构,实际上这道题考察的是位运算中的 & 和 | 。总思想没变,就是想记录每一位字符出现的次数,判断有没有重复。举个例子如何用位运算来完成记录次数的操作:
假设字符串s为“abca”,令mark=0,它来代替数组,因为位运算是数据的每一位参与的运算,一个int型数据有32位,而题目要求的小写字母'a'---'z'共26位,足够满足了。
令int temp=s[i]-'a',代表字符与'a'的距离。然后对每个字符,让1<<temp,比如s[1]即‘b’,与'a'相差1位,1左移1位后为得到‘010’,可以看到只有'b'对应下标那一位为1,其他位为0(表示出'b'的位置)。让这个数和mark相与(&:同为1才为1),因为之前没出现过'b',mark为0,故与的结果为0。若结果为0即没出现过,则要记录它现在出现了,让mark等于该结果和‘010’的或,可以得到010('b'位置就为1),若下次再遇到'b',则和mark与的结果肯定不为0,则return false。
bool isUnique(char* astr){
int mark=0;
for(int i=0;i<strlen(astr);i++)
{
int temp=astr[i]-'a';
if((mark&(1<<temp))!=0)return false;
else{
mark=mark|(1<<temp);
}
}
return true;
}
关键就在于用1来左移字符与'a'的距离个位置的值 来表示该字符在字符串中的位置,用整型mark来记录字符出现的情况;与和或的应用