题目速览
- 难度:简单
- 核心 :字符串
t是s重排后多添加一个字符,找出这个字符 - 适用技巧:暴力遍历、排序、双指针、位运算异或
解法一:暴力删除法(纯入门思路)
核心思路
遍历 s 的每个字符,在 t 中找到并删除该字符,最终 t 剩余的唯一字符就是答案。
复杂度
- 时间:O(n2)(双重循环,查找 + 删除)
- 空间:O(n)(拷贝字符串)
代码
cpp
运行
#include <string>
using namespace std;
class Solution {
public:
char findTheDifference(string s, string t) {
string res = t;
for (char ch : s) {
int pos = res.find(ch);
res.erase(pos, 1);
}
return res[0];
}
};
特点
✅ 思路最直白,零理解成本❌ 效率极低,仅用于入门理解
解法二:排序 + 双指针法(新手首选 / 面试稳过)
核心思路
- 对
s和t分别升序排序 - 双指针同步遍历,逐个比较字符
- 字符不同 →
t当前字符为答案;全部相同 →t最后一位为答案
复杂度
- 时间:O(nlogn)(排序为主)
- 空间:O(1)(原地排序,常数空间)
代码
cpp
运行
#include <algorithm>
#include <string>
using namespace std;
class Solution {
public:
char findTheDifference(string s, string t) {
// 排序
sort(s.begin(), s.end());
sort(t.begin(), t.end());
// 双指针比较
int i = 0, j = 0;
while(i < s.size() && j < t.size()){
if(s[i] != t[j]) return t[j];
i++, j++;
}
// 新增字符在末尾
return t[j];
}
};
特点
✅ 易理解、易编写、无坑、边界处理完美✅ 效率远胜暴力法,面试推荐写法❌ 会改变字符串原顺序(题目无影响)
解法三:位运算异或法(时空最优 / 进阶解法)
核心思路
利用异或三大性质:
- 相同数异或 = 0
- 0 异或任意数 = 数本身
- 满足交换律 / 结合律将
s和t所有字符异或,重复字符抵消为 0,剩余结果就是多出的字符。
复杂度
- 时间:O(n)(线性遍历,最优)
- 空间:O(1)(仅 1 个变量,最优)
代码
cpp
运行
class Solution {
public:
char findTheDifference(string s, string t) {
int ans = 0;
// 异或s所有字符
for (char ch : s) ans ^= ch;
// 异或t所有字符
for (char ch : t) ans ^= ch;
return (char)ans;
}
};
特点
✅ 代码极简、效率拉满、原地操作✅ 算法面试高频位运算用法❌ 需要理解异或原理
三种解法对比(记忆版)
| 解法 | 时间复杂度 | 空间复杂度 | 理解难度 | 推荐指数 |
|---|---|---|---|---|
| 暴力删除法 | O(n2) | O(n) | ⭐ | ❌ |
| 排序 + 双指针法 | O(nlogn) | O(1) | ⭐ | ✅⭐⭐⭐⭐ |
| 位运算异或法 | O(n) | O(1) | ⭐⭐ | ✅⭐⭐⭐⭐ |
快速记忆口诀
- 暴力删字符:笨方法,能做但慢
- 排序双指针:最稳解法,新手必背
- 异或消重复:最优解法,炫技必备
核心总结
- 入门:先写暴力删除法,保证思路正确
- 实战 :优先写排序 + 双指针,简单无坑
- 进阶 :掌握异或法,时间空间双最优
- 本题核心:找重复、消重复(贴合算法本质:暴力 + 找规律)