前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【一天一大 lee】字符串中的第一个唯一字符 (难度:简单) - Day20201223

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

作者头像
前端小书童
发布2021-01-05 10:17:28
2070
发布2021-01-05 10:17:28
举报

20201223

题目:

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

示例:

s = "leetcode"
返回 0

s = "loveleetcode"
返回 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 栏目 欢迎关注留言

公众号:前端小书童

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小书童 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:
  • 抛砖引玉
    • 遍历-哈希
      • 遍历-Unicode
        • 队列
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档