LeetCode 389. 找不同 | 三种解法笔记(暴力 / 排序双指针 / 异或最优)

题目速览

  • 难度:简单
  • 核心 :字符串 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];
    }
};

特点

✅ 思路最直白,零理解成本❌ 效率极低,仅用于入门理解


解法二:排序 + 双指针法(新手首选 / 面试稳过)

核心思路

  1. 对 s 和 t 分别升序排序
  2. 双指针同步遍历,逐个比较字符
  3. 字符不同 → 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];
    }
};

特点

✅ 易理解、易编写、无坑、边界处理完美✅ 效率远胜暴力法,面试推荐写法❌ 会改变字符串原顺序(题目无影响)


解法三:位运算异或法(时空最优 / 进阶解法)

核心思路

利用异或三大性质:

  1. 相同数异或 = 0
  2. 0 异或任意数 = 数本身
  3. 满足交换律 / 结合律将 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) ⭐⭐ ✅⭐⭐⭐⭐

快速记忆口诀

  1. 暴力删字符:笨方法,能做但慢
  2. 排序双指针:最稳解法,新手必背
  3. 异或消重复:最优解法,炫技必备

核心总结

  1. 入门:先写暴力删除法,保证思路正确
  2. 实战 :优先写排序 + 双指针,简单无坑
  3. 进阶 :掌握异或法,时间空间双最优
  4. 本题核心:找重复、消重复(贴合算法本质:暴力 + 找规律)
相关推荐
Logic1011 天前
C语言/数据结构位运算题解:异或XOR找出数轴移动中只出现一次的指令——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic1012 天前
C语言/数据结构字符串题解:解压缩“字符+次数“格式——多位数字处理与字符串还原
c语言·数据结构·字符串·模拟·时间复杂度·空间复杂度·算法题
Logic1012 天前
C语言/数据结构位运算题解:异或XOR找出糖葫芦派对中的“独一无二山楂果数量“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic1017 天前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
Logic1018 天前
C语言/数据结构位运算题解:异或XOR找出优秀项目组中的“独特编号“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic1019 天前
C语言/数据结构字符串题解:最短循环节——找出能重复构成原串的最短基础子串
c语言·数据结构·字符串·枚举·时间复杂度·算法题·kmp优化
Logic10110 天前
C语言/数据结构位运算题解:异或XOR找出英雄队伍中的“独特战斗力“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic10111 天前
C语言/数据结构动态规划题解:爬楼梯(含坏台阶)——避开障碍物的路径计数
c语言·数据结构·动态规划·时间复杂度·空间复杂度·算法题·爬楼梯
Logic10112 天前
C语言/数据结构排序题解:三个数的最大乘积——排序后比较两种候选情况
c语言·数据结构·数组·排序·时间复杂度·算法题·负数处理
Logic10112 天前
C语言/数据结构贪心算法题解:字符串趋同——逐位统计最高频率求最小修改代价
c语言·数据结构·贪心算法·字符串·时间复杂度·频率统计·算法题