【21】只出现一次的第一个字符

剑指 Offer 50. 第一个只出现一次的字符难度简单

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:

s = “abaccdeff”
返回 “b”

s = “”
返回 " "

方法一 使用HashMap储存字符出现的频数
//1.使用HashMap储存字符出现的频数
//2.将字符串s转换为char型数组 toCharArray()。
//3.记录每个字符出现的频数
//关键:getOrDefault(c,0)方法,如果map中存在值为c的key,就获取c对应的value,如果不存在key:c,则返回默认值0。
//4.遍历字符串s,找到第一个出现次数为1的字符。注意是遍历字符串s。而不是遍历HashMap。

class Solution {
    public char firstUniqChar(String s) {
    
      HashMap<Character,Integer> frequency =new HashMap<Character,Integer>();
        
         char[] chars = s.toCharArray();
  
         for(char c:chars)
          frequency.put(c,frequency.getOrDefault(c,0)+1);       
        
         for(char c:chars)
           if(frequency.get(c) == 1) return c;
         
return ' ';
    }
}

拓展:如果此题改为第一个出现的数字,则同样适用。如果没有要求找到最小的那个数,或者最小的字符(a),可以直接遍历数组,不用担心key值存放到map后无序的问题。因为每个key对应一个value,先存放的key就对应着先遍历到的下标。

方法二:使用LinkedHashMap,两次遍历实现。第一次遍历将所有字符当作key存入LinkedHashMap,map.put(c, !map.containsKey©)这一句当map中不存在c字符时,将c对应的value设为true;存在时设为false。则当遍历结束时,没有重复的字符对应的value都为true。然后我们通过get得到第一个value值为true的c字符就可了。
代码

class Solution {
    public char firstUniqChar(String s) {
      //为什么使用LinkedHashMap呢?因为LinkedHashMap底层实现是一个哈希表+双向链表。它可以让我们在使用get(c)方法时,得到第一个放入的c元素。
         char[] chars = s.toCharArray();
         for(char c:chars){
   HashMap<Character,Boolean> map =new LinkedHashMap<Character,Boolean>();
            //  map.put(c,!containsKey(c));
              map.put(c, !map.containsKey(c));//如果c字符已经出现过一次(即以及存在与hashmap中)就把它对应的value值设为false。
        }

//如果s不是有序的则需要遍历LinkedHhashMap,才能保证第二遍遍历时key是有序的。
//因为字符串s即chars数组中的字符本来就是有序的,所以直接遍历s,得到的hashmap中的value就是第一个只出现一次的字符。
         for(char c:chars){
            if(map.get(c)) return c;
         } 
         return ' ';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值