题目:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = "leetcode"
返回 0
s = "loveleetcode"
返回 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 栏目
欢迎关注留言