力扣387. 字符串中的第一个唯一字符

207 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

力扣387. 字符串中的第一个唯一字符

一、题目描述:

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

示例 1:

输入: s = "leetcode" 输出: 0 示例 2:

输入: s = "loveleetcode" 输出: 2 示例 3:

输入: s = "aabb" 输出: -1

提示:

1 <= s.length <= 10^5 s 只包含小写字母

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/fi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    这道题目,我的初始思路是先计算每个字符出现的频率,然后再遍历字符串,返回第一个频率为1的字符的索引,如果不存在就返回-1.

    还有一种思路,就是使用哈希表存储索引,遍历字符串,如果ch在字符串中出现第一次就存储存储它的索引,如果出现第二次就将索引变为-1,最后在查找第一个索引不为-1的最小索引。

  1. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    是一次通过的,本题只需要理清思路即可快速解题。需要细心。

  2. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    看到了大佬写的利用队列的方法

    image-20220322110120368

 class Solution {
     public int firstUniqChar(String s) {
         Map<Character, Integer> position = new HashMap<Character, Integer>();
         Queue<Pair> queue = new LinkedList<Pair>();
         int n = s.length();
         for (int i = 0; i < n; ++i) {
             char ch = s.charAt(i);
             if (!position.containsKey(ch)) {
                 position.put(ch, i);
                 queue.offer(new Pair(ch, i));
             } else {
                 position.put(ch, -1);
                 while (!queue.isEmpty() && position.get(queue.peek().ch) == -1) {
                     queue.poll();
                 }
             }
         }
         return queue.isEmpty() ? -1 : queue.poll().pos;
     }
 ​
     class Pair {
         char ch;
         int pos;
 ​
         Pair(char ch, int pos) {
             this.ch = ch;
             this.pos = pos;
         }
     }
 }

三、AC 代码:

思路一:

Python:

 class Solution:
     def firstUniqChar(self, s: str) -> int:
         Frequency = collections.Counter(s)
 ​
         for i,ch in enumerate(s):
             if(Frequency[ch] == 1):
                 return i
 ​
         return -1

image-20220322111028400

image-20220322111045282

Java:

 class Solution {
     public int firstUniqChar(String s) {
         Map<Character,Integer> frequency = new HashMap<Character,Integer>();
 ​
         for(int i=0;i<s.length();i++){
             char c = s.charAt(i);
             frequency.put(c,frequency.getOrDefault(c,0) + 1);
         }
 ​
         for(int i=0;i<s.length();i++){
             if(frequency.get(s.charAt(i)) == 1){
                 return i;
             }
         }
         return -1;
     }
 }

image-20220322111058506

image-20220322111109776

思路二:

Python:

 class Solution:
     def firstUniqChar(self, s: str) -> int:
         position = dict()
         n = len(s)
         for i, ch in enumerate(s):
             if ch in position:
                 position[ch] = -1
             else:
                 position[ch] = i
         first = n
         for p in position.values():
             if p != -1 and p < first:
                 first = p
         if first == n:
             first = -1
         return first

四、总结:

本题要求我们掌握哈希表的使用,对于Python中collections.Counter(s)和enumerate(s)的使用,已经Java中queue.offer(new Pair(ch, i)); 和queue.poll().pos、queue.isEmpty()等队列的相关操作使用需要掌握。