题目描述
面试题 01. 判定字符是否唯一
实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
示例 1:
输入: s = "leetcode"
输出: false
示例 2:
输入: s = "abc"
输出: true
限制:
0 <= len(s) <= 100
s[i]仅包含小写字母
如果你不使用额外的数据结构,会很加分。
解题思路1:
题目本质是判断是否含有重复元素, 我们可以使用set, dict这种数据结构进行判断; 同时也可以借助一些系统内置函数减少代码量
示例代码
# 直接使用set结构, 进行遍历
def isUnique1(self, astr: str) -> bool:
use = set()
for item in astr:
if item in use:
return False
else:
use.add(item)
return True
# 使用count() 内置函数, 判断字符数量是否大于1
def isUnique2(self, astr: str) -> bool:
for c in astr:
if astr.count(c) > 1:
return False
return True
# 使用Counter 内置对象, 进行长度对比
def isUnique3(self, astr: str) -> bool:
return len(Counter(astr).values()) == len(astr)
# 使用 set() 内置对象, 进行长度量对比
def isUnique4(self, astr: str) -> bool:
return len(set(astr)) == len(astr)
解题思路2:
如果只是简单的使用内置函数进行判断, 那这个题目最后的限制就显的没有意义了, 所以肯定有其他更好的方案. 那就是 -> 位运算
对于每个字符, 我们可以使用 ASCII码作为数组的idx, dict的key等.
- 在一个数组中, 如果idxN没有元素, 那么我们将遍历的字符放进数组中
- 如果idxN已有的元素与当前遍历的字符相等, 那么这个字符就是重复字符. 否则直到字符串遍历完成, 得出没有重复字符.
- 因为这个题目我们不需要知道具体字符是什么, 所以就可以借助位运算来做. 将1左移"ASCII位"后得到一个类似于数组的int, 通过 & 操作与之前的结果进行对比判断字符是否相等, 通过 | 操作对不相等的元素进行"放进数组" 操作
示例代码
def isUnique(self, astr: str) -> bool:
# 保存结果的"数组"
mask = 0
for item in astr:
# ASCII码计算, 减去'a' 方便计算
position = ord(item) - ord('a')
# "数组中"的 idxN 与当前元素 进行对比
if mask & (1 << position) != 0:
# 根据 & 操作, 如果结果不等于0, 则表示idxN有相同元素
return False
else:
# 根据 & 操作, 如果结果等于0, 则认为idxN没有相同元素, 通过 | 操作将当前元素存入"数组"
mask |= (1 << position)
return True