精品题解 🔥 《九章斩题录》 👈 猛戳订阅
面试题 01.01. 判定字符是否唯一
✅ 模板:C语言
class Solution {
public:
bool isUnique(string astr) {
}
};
💭 思考:《程序员面试金典》里的题,这题和剑指Offer的 "数组中重复的数字" 几乎一模一样啊,只是重复的数字变成了重复的字符,判断 "重复" 和判断 "是否唯一" 在这里实际上是一样的。
「 法一 」暴力大法
💡 思路:用两个 for 暴力,外层 for 依次选定一个锚点,然后内层 for 从锚点下一个位置开始找。找到相同的就说明不是唯一的,我们返回 false。如果循环结束仍然没找到,那就说明字符都是唯一的,返回 true。优点就是简单,但时间复杂度是 。
💬 代码演示:
class Solution {
public:
bool isUnique(string astr) {
for (int i = 0; i < astr.size(); i++) {
for (int j = i + 1; j < astr.size(); j++) {
if (astr[i] == astr[j]) {
return false;
}
}
}
return true;
}
};
🚩 运行结果如下:
「 法二 」哈希无序集
💡 思路:既然要找是否唯一,很容易想到用哈希,这里可以利用 unordered_set。既然要找重复的元素,本质上就是看是否 unique (唯一),这让我们想到了数学中的集合,可以利用 "集合元素是唯一的" 的特点。拿题目中的例子来说,如果我们以集合的方式存储一遍该字符串,那么如果在存储过程中出现重复,那么不就找到我们想要的 target 了吗?
我们知道,set 的底层是红黑树,时间复杂度为 ,而 unordered_set 的期望复杂度能够达到 。所以这里我们选择使用 unordered_set。
unordered_set 我们仍然是用 count 来检查是否在 hash 表内,用 insert 来插入。
💬 代码演示:
class Solution {
public:
bool isUnique(string astr) {
unordered_set<char> u_set;
for (int i = 0; i < astr.size(); i++) {
if (u_set.count(astr[i]) == 0) {
u_set.insert(astr[i]);
}
else {
return false;
}
}
return true;
}
};
🚩 运行结果如下:
「 法三 」排序 + 遍历
💡 思路:我们可以尝试 "排序 + 遍历" 的方法,先对字符串进行排序,因为排序后,相同的字符肯定是紧挨着的,如此一来,我们只需要一层循环遍历一遍排序完的字符串即可。遍历时将下标 设置从 1 开始,依次和 下标的元素做对比即可。排序可以直接调 sort。
💬 代码演示:
class Solution {
public:
bool isUnique(string astr) {
sort(astr.begin(), astr.end());
for (int i = 1; i < astr.size(); i++) {
if (astr[i - 1] == astr[i]) {
return false;
}
}
return true;
}
};
「 法四 」st 数组
💡 思路:在遍历字符串时,使用 st 数组记录当前字符,如果该字符存在则说明该字符不是唯一。
class Solution {
public:
bool isUnique(string astr) {
bool st[10000] = { 0 }; // 初始化为0
for (int i = 0; i < astr.size(); i++) {
if (st[ astr[i] ] != 0) { // 如果不为0
return false;
}
st[ astr[i] ] = 1; // 设置为1
}
return true;
}
};
「 法五 」位运算
💡 思路:题目说不使用额外数据结构加大分,好好好。
class Solution {
public:
bool isUnique(string astr) {
int mark = 0;
int move_bit = 0;
for (auto e : astr) {
move_bit = e - 'a';
if (mark & (1 << move_bit)) {
return false;
}
else {
mark |= (1 << move_bit);
}
}
return true;
}
};
📌 [ 笔者 ] 王亦优
📃 [ 更新 ] 2023.
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!
📜 参考资料 C++reference[EB/OL]. []. http://www.cplusplus.com/reference/. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/. 牛客网. 剑指offer 题解 [EB/OL]. []. https://www.nowcoder.com/exam/oj/ta?tpId=13. |