LeetCode《初级算法》字符串之字符串中的第一个唯一字符 -- JavaScript

378 阅读1分钟

题目

题目链接:leetcode-cn.com/leetbook/re…

image.png

题解


1、暴力方法

第一个想到的就是直接两层循环套上去,虽然简单,但却有用,上代码;

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {

    let isReapet = false;
    let len =  s.length;

    for(let i = 0;i < len;i++) {
        isReapet = false;

        for(let j = 0;j<len;j++) {
            if( i !== j && s[i] === s[j]) {
                isReapet = true;
                break;
            }
        }

        if(isReapet === false) {
            return i;
        }
    }

    return -1;

};


2、改进:空间换时间

暴力方法的时间复杂度是O(nlog2n)O(nlog_2n),肯定会想去降低它的时间复杂度,按照空间换时间的理论,看能不能在 O(n)O(n)的时间复杂度内完成; 如下,使用 对象(当然这里也可以用 Map)先记录字符是否重复,再找出第一个不重复字符的位置;

使用 Object 记录

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {

    let len =  s.length;
    let isRepeat = {};

    for(let item of s) {
        if( isRepeat[item] === undefined) {
            isRepeat[item] = false;
        }else {
            isRepeat[item] = true;
        }
    }
    for(let i = 0;i < len;i++) {
        if(isRepeat[s[i]] === false) {
            return i;
        }
    }
    return -1;

};

使用 Map 记录

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {

    let len =  s.length;
    let map = new Map();

    // 使用一个 Map 将字符是否重复记录下来,重复则值为true,不重复则值为false
    for(let item of s) {

        if( map.get(item) === undefined) {
            map.set(item,false);
        }else {
            map.set(item,true);
        }

    }

    for(let i = 0;i < len;i++) {
        if(map.get(s[i]) === false) {
            return i;
        }

    }

    return -1;

};

既然 Object 和 Map 都能使用,它们之间有什么区别呢? 如下,From MDN

  • Object 继承了原型链上的所有键名,因此可能和自己设置的键名产生冲突;而 Map 默认只包含了自己的键名;

  • Object 的键必须是一个 String 或 Symbol;而 Map 的键可以是任意类型;

  • Object 的键是无序的,Map 中的键的顺序和插入顺序一致;

  • Object 的键值对个数只能手动计算,Map 中可以通过 size 获取;

  • Object 不是可迭代的,Map 是可迭代的;

  • 在频繁增删键值对的场景下,Map 表现更好;


3、改进:使用 JS 字符串的方法

str.indexOf()str.lastIndexOf() 确定字符在字符串中第一次和最后一次出现的位置;

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {

    let len =  s.length;
    
    for(let i = 0;i < len;i++) {
        var str = s[i];
        if(s.indexOf(str) === s.lastIndexOf(str)) {
            return i;
        }
    }
    return -1;

};

大家如果有更好的思路和解法,欢迎大家一起来讨论啊~

这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里:

juejin.cn/post/700669…