34 第一个只出现一次的字符

 题目要求:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

 方法一: 用键值对

 1 import java.util.*;
 2 public class Solution {
 3     public int FirstNotRepeatingChar(String str) {
 4         if(str.length()==0) return -1;//这句加不加都能通过所有的测试用例
 5         //用HashMap和LinkedHashMap都可以
 6         HashMap<Character, Integer> map = new HashMap<Character, Integer>();
 7         //遍历String的每一个字符,将其存入<K,V>键值对中
 8         for(int i=0;i<str.length();i++){
 9             if(map.containsKey(str.charAt(i))){
10                 //一开始我还纠结time的初始值怎么没有设置,看14行代码啊
11                 int time = map.get(str.charAt(i));
12                 time++;
13                 map.put(str.charAt(i),time); //删去11行,将12行改为 ++time也可以
14             }else{
15                 //遇到了新的char,存入新的键值对
16                 map.put(str.charAt(i),1);
17             }
18         }
19         for(int j=0;j<str.length();j++){
20             if(map.get(str.charAt(j))==1) return j;
21         }
22         return -1;
23     }
24 }

 

hashmap是根据hash值来存储的,而linkedhashmap底层是链表,可以根据顺序存储。比如说输入c,a,hashmap存储计算出c,a的hash值,有可能存成a,c,而linked存储为c,a不会改变输入顺序

不是根据顺序存储,二者都是以hash的形式存储,内部都是hash数组,只不过后者还存储了插入的顺序,使用迭代器迭代的时候应该能反映出来。

人家最后是按照str的顺序遍历的,所以存储时个顺序无关

这题用啥map没啥区别的……因为他最后又在字符串中遍历了一遍。如果非要用到LinkedHashMap的特性的话,可以先遍历LinkedHashMap找到第一个value为1的key,然后str.indexOf(key)就是所求的结果。

都试过了,LinkedHashMap时间复杂度更低一点,

LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。也可以在构造时用带参数,按照应用次数排序。

方法二:数组

链接:https://www.nowcoder.com/questionTerminal/1c82e8cf713b4bbeb2a5b31cf5b0417c
来源:牛客网

说一下解题思路哈,其实主要还是hash,利用每个字母的ASCII码作hash来作为数组的index。首先用一个58长度的数组来存储每个字母出现的次数,为什么是58呢,主要是由于A-Z对应的ASCII码为65-90,a-z对应的ASCII码值为97-122,而每个字母的index=int(word)-65,比如g=103-65=38,而数组中具体记录的内容是该字母出现的次数,最终遍历一遍字符串,找出第一个数组内容为1的字母就可以了,时间复杂度为O(n)

 1 链接:https://www.nowcoder.com/questionTerminal/1c82e8cf713b4bbeb2a5b31cf5b0417c
 2 来源:牛客网
 3 
 4 public static int solution(String str){
 5     int[] words = new int[58];
 6     for(int i = 0;i<str.length();i++){
 7         words[((int)str.charAt(i))-65] += 1;
 8     }
 9     for(int i=0;i<str.length();i++){
10         if(words[((int)str.charAt(i))-65]==1)
11             return i;
12     }
13     return -1;
14 }

 

猜你喜欢

转载自www.cnblogs.com/shareidea94/p/11125686.html