一开始想用HashMap,把每个字符放进去,然后统计出现的次数。
使用LinkedHashMap的话,键值对的顺序都是不会变的。
LinkedHashMap<Character,Integer> map = new LinkedHashMap<>(); map.put('i',1111); map.put('j',2222); map.put('k',3333); map.put('l',4444); //LinkedHashMap的values也是按key的顺序吗? Collection<Integer> values = map.values(); Iterator<Integer> iterator = values.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); }
输出的值是1111,2222,3333,4444
所以按照题目,只要判断出第一个出现次数为1的字符即可。
但是,无法找到正确的下标。
比如aaabbbbcaaad。
怎么知道c的下标呢?
很难。
最好的办法就是自定义一个数据结构,Map里面存这个结构
public static class Node{ //值 public char val; //第一次出现的下标 public int index; //出现的次数 public int count; public Node(char val,int index,int count){ this.val = val; this.index = index; this.count = count; } }
这样,就能按照出场顺序记录每个字符了。相对位置是绝对正确的
还能获取他们的个数。以及首次出现的位置。
public int firstUniqChar(String s) { //空的就是找不到 if(s==null||s.length()==0){ return -1; } LinkedHashMap<Character,Node> map = new LinkedHashMap<>(); for(int i=0,len=s.length();i<len;i++){ Node temp = map.get(s.charAt(i)); if(temp==null){ map.put(s.charAt(i),new Node(s.charAt(i),i,1)); }else { //这两个引用,指向的是同一个地方,所以直接在这++就好了 temp.count++; } } //结果也是按顺序的,找到最先出现那个即可 Collection<Node> values = map.values(); Iterator<Node> iterator = values.iterator(); Node result = null; while(iterator.hasNext()){ result = iterator.next(); if(result.count==1) break; } //如果最后是次数1的就返回,如果最后还没有次数1的,就是找不到 if(result.count==1){ return result.index; }else { return -1; } }