问题描述:给定一个字符串 s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
。
(来源:leetcode)
解法一:暴力解法
思路:双重for循环判断每一个元素是否存在重复,若存在,第三层for循环把所有重复项找出,并终止第二层for循环;若不存在,则让第二层for循环走到最后
var firstUniqChar = function(s) {
if(s.length <= 1) return 0
let arr = []
let i, j, k
for(i = 0; i < s.length; i++){
//判断i是不是已经存在重数了
if(arr[i]) continue
for(j = i + 1; j < s.length; j++){
//如果查到重数,把所有重数都查出来
if(s[i] == s[j]){
arr[i] = arr[j] = 1
for(k = j + 1; k < s.length; k++){
if(s[k] == s[i]) arr[k] = 1
}
break
}
}
//判断是否走到了最后,若是,则说明当前s[i]是所求结果,返回其下标
if(j == s.length) return i
}
//若上面的嵌套for循环走完了,那么说明不存在不重复项,返回-1
return -1
}
解法二:两次遍历
思路:用一个数组存每个出现的元素出现的次数,再查每个元素出现的次数,第一个等于1的就是我们要找的元素。在这个算法中,最重要的是计算出每个字母的固定下标:字母的ascii值 - a的ascii值
var firstUniqChar = function(s) {
//创建能包含26个字母的数组,初始化值均为0
let num = new Array(26).fill(0)
//存储26个字母的出现次数
for(let i = 0; i < s.length; i++){
num[s[i].charCodeAt() - 'a'.charCodeAt()]++
}
//判断第一个不重复元素
for(let i = 0; i < s.length; i++){
if(num[s[i].charCodeAt() - 'a'.charCodeAt()] == 1) return i
}
//找不到返回-1
return -1
}
解法三:API: lastIndexOf (JavaScript)
思路:js中的两个api的使用:
indexOf 返回数组中第一个某元素的下标
lastIndexOf 返回数组中最后一个某元素的下标,若该元素只有一个,那么就返回其下标
即:当 indexOf() == lastIndexOf()时,说明该元素只有一个
var firstUniqChar = function(s) {
for(let i = 0; i < s.length ; i++){
if(s.indexOf(s[i]) == s.lastIndexOf(s[i])) return i
}
return -1
}