zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    【Android 7.1.1】 锁屏界面点击“空白处”响应事件
    ubuntu14.04 LTS Visual Studio Code 编辑器推荐
    使用MAT分析Java内存
    Android 性能优化:使用 Lint 优化代码、去除多余资源
    Android 内存使用hprof文件打开方法
    使用Android Studio调试内存问题
    使用新版Android Studio检测内存泄露和性能
    Android性能优化篇 [ 谷歌官方 ]
    Android 内存泄露总结(附内存检测工具)
    Android MemInfo 各项的意义(转)
  • 原文地址:https://www.cnblogs.com/Yi-ling/p/14182973.html
Copyright © 2011-2022 走看看