You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript高效查找字符串中的第一个非重复字符?

如何用JavaScript高效查找字符串中的第一个非重复字符?

兄弟,你这个问题抓得特别准!你已经意识到嵌套循环O(n²)的效率瓶颈,而且方向也找对了——用哈希表类的数据结构就能把时间复杂度降到O(n),我来给你一步步拆解实现思路和代码:

优化核心思路

我们可以把问题拆成两次线性遍历,用空间换时间:

  1. 第一次遍历:用哈希表(比如JS的Map或普通对象)统计每个字符的出现次数,这一步时间复杂度O(n)
  2. 第二次遍历:再扫一遍原字符串,去哈希表里查每个字符的计数,第一个出现次数为1的字符就是我们要找的结果,这一步也是O(n)
    整体时间复杂度是O(n),空间复杂度是O(k)(k是字符串中不同字符的数量),完全解决了长字符串的性能问题。

优化后的代码实现

这里我用Map来实现(它的键值对结构天生适合统计,逻辑更直观):

function findFirstNonRepeatingChar(str) {
    // 第一步:统计每个字符的出现次数
    const charCount = new Map();
    for (const char of str) {
        charCount.set(char, (charCount.get(char) || 0) + 1);
    }

    // 第二步:遍历原字符串,找第一个出现次数为1的字符
    for (const char of str) {
        if (charCount.get(char) === 1) {
            return char;
        }
    }

    // 没有找到非重复字符,返回null
    return null;
}

如果你更习惯用普通对象(逻辑和Map完全一致,只是语法不同),也可以这么写:

function findFirstNonRepeatingChar(str) {
    const charCount = {};
    for (const char of str) {
        charCount[char] = (charCount[char] || 0) + 1;
    }

    for (const char of str) {
        if (charCount[char] === 1) {
            return char;
        }
    }

    return null;
}

代码逻辑拆解

  1. 统计阶段:
    • 遍历字符串的每个字符,用charCount记录出现次数:如果字符已经在表里,就把计数加1;如果是第一次遇到,就初始化为1。
  2. 查找阶段:
    • 必须再次遍历原字符串(保证按输入顺序查找),检查每个字符的计数,第一个计数为1的直接返回——这一步是确保我们拿到的是「第一个」非重复字符,而不是哈希表中先统计到的。
  3. 边界处理:如果遍历完所有字符都没有找到计数为1的,返回null。

测试验证

用你给出的例子测试:

console.log(findFirstNonRepeatingChar("swiss")); // 输出 "w"
console.log(findFirstNonRepeatingChar("aabbcc")); // 输出 null

完全符合预期,而且处理10万级别的长字符串时,性能会比你原来的嵌套循环快几个数量级。

额外小提示

如果需要不区分大小写的查找(比如把"S"和"s"视为同一个字符),只需要在统计和查找时把字符统一转成小写(或大写)即可:

// 统计阶段
const lowerChar = char.toLowerCase();
charCount.set(lowerChar, (charCount.get(lowerChar) || 0) + 1);

// 查找阶段
if (charCount.get(char.toLowerCase()) === 1) {
    return char;
}

备注:内容来源于stack exchange,提问作者nikhil pachange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:59:35