LeetCode387-字符串中的第一个唯一字符 | 算法练习系列

134 阅读2分钟

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

前言

js每日一题算法题,今天来一道简单难度的字符串处理问题,话不多说,下面直接看题目

题目描述

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

  示例:

s = "leetcode"

返回 0

s = "loveleetcode"

返回 2  

提示:你可以假定该字符串只包含小写字母。

解题思路

  • what?题目这么简单,短短的两句话,那不是信手拈来嘛,首先根据题目是要求第一个不重复字符的索引,那我们直接两层for循环不就解决问题了嘛,但这种操作也太暴力了,性能很差
  • 我们可以使用indexOf和lastIndexOf来解决问题,哇,这种方法代码也太简洁了,如下
/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {
    let n = s.length
    for(let i=0;i<n;i++){
        if(s.indexOf(s[i])===s.lastIndexOf(s[i])){
            return i
        }
    }
    return -1
};
  • emmm。。。提交也通过了

第一.PNG

  • 但这种方法的性能其实也很低,因为indexOf和lastIndexOf的底层实现也是用的for循环,也行想当的消耗资源
  • 那我们就再换种方法,我们这次用哈希表来解决问题,使用哈希表解决方法的思路是首先循环目标字符串,把字符当键,下标当值存入map中,首先就是循环目标数组,把每个字符存入map中,这里要注意,如果map中不存在这个字符,那这个字符对应的值就是当前下标,否则对应的值直接设置为-1,当循环结束之后我们再进行一次循环,判断map中第一个值不为-1的项,这个项对应的值就是我们所求的正确答案,下面上代码
/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {
    const n = s.length
   let map = {} //这里用对象或者数组都可以
   for(let i=0;i<n;i++){
       if(map[s[i]]||map[s[i]]===0){//这里要多一个map[s[i]]===0的判断,因为字符串的第一个字符下标是0
           map[s[i]] = -1
       }else{
           map[s[i]] = i
       }
   }
   for(let j=0;j<n;j++){
       if(map[s[j]]!==-1){
           return map[s[j]]
       }
   }
    return -1 //如果循环结束都没return,那么说明不存在没重复的字符,这里就要return -1
};
  • 运行结果比上面的方法要好不少,如下

啦啦啦.PNG

总结

本题大致就是如此,越来越感觉map这种数据结构很好用,继续学习,gogogo!!!