LeetCode --- 字符串系列 --- 字符串中的第一个唯一字符
字符串中的第一个唯一字符
题目
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例
示例 1:
s = "leetcode"
返回 0.
示例 2:
s = "loveleetcode",
返回 2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-unique-character-in-a-string/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
渐进解法1
1、循环字符串,获取 `第一个字符串` ,设置一个 `匹配全局` 的正则
2、若全局匹配到的结果只有一个,则该字符的位置即为结果
3、若全局匹配到的结果不止一个,去掉字符串中的所有 `当前匹配字符`
拿剩下的字符串继续循环
渐进解法2
1、循环字符串,使用 `当前字符` 作为对象 `obj` 的 `key` ,初始化 `obj[key]` 为对象
并设置 count 和 index 为属性,存储累计出现 `次数` 与 `下标`
2、判断 `第一个属性` `count` 为 1 的 `下标` 即为结果
力扣较好题解
1、使用字符串的 `indexOf` 和 `lastIndexOf` 这两个 `api`
字符 `第一次出现的位置` 和 `最后一次出现的位置` 若相等,那么肯定是唯一的
题解
渐进解法1
// 运行时间有点长、使用内存有点大
执行用时: 336 ms
内存消耗: 41.5 MB
let firstUniqChar = function(s) {
let cps = s
while(cps.length > 0) {
// 获取第一个字符串,设置一个匹配全局的正则
let r = new RegExp(cps[0], 'g')
// 匹配全局
let m = cps.match(r)
// 若全局只有一个,则该字符的位置即为结果
if (m.length === 1) {
return s.indexOf(cps[0])
} else {
// 若全局不止一个,去掉字符串中的所有当前匹配字符
cps = cps.replace(r, '')
}
}
return -1
};
渐进解法2
// 运行时间有点长、使用内存一般
执行用时: 140 ms
内存消耗: 38.4 MB
let firstUniqChar = function(s) {
let cur = {}, i = 0
while(i < s.length) {
let x = s[i]
cur[x] = cur[x] ? cur[x] : {}
// 使用当前字符作为 key ,初始化为对象
// 设置 count 和 index ,存储累计出现次数与下标
if (cur[x].count) {
++cur[x].count
} else {
cur[x].count = 1
cur[x].index = i
}
i++
}
// 循环得到的外层对象
// 判断第一个属性 count 为 1 的下标即为结果
for (const c in cur) {
if (cur[c].count === 1) {
return cur[c].index
}
}
return -1
};
力扣较好题解
// 运行时间一般、使用内存挺好
执行用时: 104 ms
内存消耗: 37.6 MB
let firstUniqChar = function(s) {
let i = 0
while(i < s.length) {
// 使用字符串的 indexOf 和 lastIndexOf 这两个 api
// 字符第一次出现的位置和最后一次出现的位置若相等,那么肯定是唯一的
if (s.indexOf(s[i]) === s.lastIndexOf(s[i])) {
return i
}
i++
}
return -1
};
都读到最后了、留下个建议如何