【一天一大 lee】字符串中的第一个唯一字符 (难度:简单) - Day20201223

【一天一大 lee】字符串中的第一个唯一字符 (难度:简单) - Day20201223_第1张图片

题目:

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例:

s = "leetcode"
返回 0

s = "loveleetcode"
返回 2

提示:

你可以假定该字符串只包含小写字母

抛砖引玉

【一天一大 lee】字符串中的第一个唯一字符 (难度:简单) - Day20201223_第2张图片

遍历-哈希

两次遍历:

  1. 统计每个字符的数量
  2. 返回第一次遇到的数量只有 1 的字符索引

如果没有遇到数量为 1 的字符返回-1

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {
    const map = new Map()
    for (const c of s) {
        map.set(c, (map.get(c) || 0) + 1)
    }
    for (let i = 0; i < s.length; i++) {
        if (map.get(s[i]) === 1) return i
    }
    return -1
}

遍历-Unicode

提示中提到字符串只包含小写字母,则说明字符的 Unicode 是可以使用的

那么参照上面的遍历思路,声明一个长 26 的数组,按照字符的 Unicode-97 将其数量对应填充到数组中

var firstUniqChar = function(s) {
    const list = Array(26).fill(0)
    for (const c of s) {
        list[c.charCodeAt() - 97]++
    }
    for (let i = 0; i < s.length; i++) {
        if (list[s[i].charCodeAt() - 97] === 1) return i
    }
    return -1
}

队列

队列(queue):先进先出

遇到新字符第一次出现直接进入队列中,且标记其索引

遇到已经出现过的字符则将其出现的索引位置标记为-1,且将其从队列中的移除

var firstUniqChar = function(s) {
    const queue = [],
        // 标记字符出现的次数
        map = new Map()
    for (let i = 0; i < s.length; i++) {
        if (!map.has(s[i])) {
            map.set(s[i], i)
            queue.push([s[i], i])
        } else {
            map.set(s[i], -1)
            // 注意此时s[i]不一定在队列头部,需要遍历队列找出要移除的字符
            while (queue.length && map.get(queue[0][0]) === -1) queue.shift()
        }
    }
    return queue.length ? queue[0][1] : -1
}

博客: 前端小书童

每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目
欢迎关注留言

公众号:前端小书童

你可能感兴趣的:(一天一大leet,leetcode,javascript,前端)