Java程序设计:字符中的第一个唯一字符(leetCode:387)体验Map+Queue队列解题

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

 示例:

  s = "leetcode"
  返回 0

  s = "loveleetcode"
  返回 2

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-unique-character-in-a-string

题解一:1、根据给定的字符串,转化为数组存储字符出现的个数;2、重新遍历字符串,首次出现字符在个数数组中值为1,则返回改字符的索引。

 1 public int firstUniqChar(String s) {
 2         // Map<Character,Integer> frequency = new HashMap();
 3         // for(int i=0;i<s.length();i++){
 4         //     char ch = s.charAt(i);
 5         //     frequency.add(ch,frequency.getOrDefault(ch,0)+1);
 6         // }
 7         // for(int i=0;i<s.length();i++){
 8         //     if(frequency.get(s.charAt(i))==1){
 9         //         return i;
10         //     }
11         // }
12         // return -1;
13 
14         int[] count = new int[26];
15         for(int i=0;i<s.length();i++){
16             char ch = s.charAt(i);
17             count[ch-'a']++;
18         }
19 
20         for(int i=0;i<s.length();i++){
21             if(count[s.charAt(i)-'a']==1){
22                 return i;
23             }
24         }
25         return -1;
26     }

题解二:1、类似题解一,用Map来存储字符和出现次数;2、遍历字符串,根据字符去Map中找次数,首次找到值为1的字符,返回其索引。

 1 public int firstUniqChar(String s) {
 2         Map<Character,Integer> frequency = new HashMap();
 3         for(int i=0;i<s.length();i++){
 4             char ch = s.charAt(i);
 5             frequency.put(ch,frequency.getOrDefault(ch,0)+1);
 6         }
 7         for(int i=0;i<s.length();i++){
 8             if(frequency.get(s.charAt(i))==1){
 9                 return i;
10             }
11         }
12         return -1;
13 
14        
15     }

题解三:1、改用Map存储字符和对应的索引(第一次出现才保存索引,否则保存-1);2、遍历Map中的键值对Entry,直到找到索引不为-1且索引值最小的,返回索引。

 1 public int firstUniqChar(String s) {
 2        //用hash表存储索引
 3        //判断值,如果值是第一次出现,则保存索引;如果是多次出现,则将索引修改为-1
 4        Map<Character,Integer> position = new HashMap();
 5        int n = s.length();
 6        for(int i=0;i<n;i++){
 7            char ch = s.charAt(i);
 8            if(position.containsKey(ch)){
 9                position.put(ch,-1);
10            }else{
11                position.put(ch,i);
12            }
13        }
14        int first = n;
15        for(Map.Entry<Character,Integer> entry:position.entrySet()){
16            int pos = entry.getValue();
17            if(pos!=-1 && pos < first){
18                first = pos;
19            }
20        }
21        if(first == n){
22            return -1;
23        }
24        return first;
25 
26 
27        
28     }

题解四:1、Map+队列融合使用,首先判断Map中是否存在字符,如果没有,使用Map保存字符和索引,同时加入队列中;如果存在,则进一步判断队首;2、借助队列先进先出的特性,只要将重复值和对首比较,队首值重复则出队。;2、如果队不为空,则取出队首对应的索引

 1 class Solution {
 2     public int firstUniqChar(String s) {
 3       //借助队列找到一个不重复的字符。队列具有【先进先出】的性质,因此很适合用来找出第一个满足某个条件的元素
 4       //具体地,我们使用与方法二相同的哈希映射,并且使用一个额外的队列,按照顺序存储每一个字符以及他们第一次出现的位置。
 5       //当我们对字符串进行遍历时,设当前遍历到的字符为c,如果c不在哈希映射中,我们就将c与它的索引作为一个二元组放入队尾,否则我们就需要检查队列
 6       //中的元素是否都满足【只出现一次】的要求,即我们不断地根据哈希映射中存储的值(是否为1)选择弹出队首的元素,知道队首元素【真的】只出现了一
 7       //次或者队列为空。
 8 
 9       //在遍历完成后,如果队列为空,说明没有不重复的字符,返回为-1,否则队首的元素即为第一个不重复的字符以及其索引的二元组。
10 
11         Map<Character,Integer> position = new HashMap();
12         int n = s.length();
13         Queue<Pair> queue = new LinkedList<Pair>();
14         for(int i=0;i<n;i++){
15             char ch = s.charAt(i);
16             if(!position.containsKey(ch)){
17                 position.put(ch,i);
18                 queue.offer(new Pair(ch,i));
19             }else{
20                 position.put(ch,-1);
21                 //当队列不为空,且当前队列中队首的取出元素在hash中对应的索引,如果是-1,则删除队首
22                 while(!queue.isEmpty() && position.get(queue.peek().ch) == -1){
23                     queue.poll();
24                 }
25             }
26         }
27         //对比完所有字符之后,取出队首元素,队为空,则返回-1
28         return queue.isEmpty() ? -1:queue.peek().pos;
29 
30     }
31 
32     class Pair{
33         char ch;
34         int pos;
35 
36         Pair(char ch,int pos){
37             this.ch = ch;
38             this.pos = pos;
39         }
40     }
41 }
原文地址:https://www.cnblogs.com/Yi-ling/p/14182973.html