剑指offer50.第一个只出现一次的字符

题目描述

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

解析
解法一
  • 遍历字符串,用HashMap<k,v>存储<字符,字符出现的次数对>,再遍历哈希表,当当前键的值为1时,返回当前键。(第一次用的是HahsMap,提交代码后执行错误,本地debug才发现put到哈希表时,顺序发生了变化,因此用LinkedHashMap代替HahsMap)
  • 代码
public char firstUniqChar(String s) {
        if(s.length()==0) return 32;
		LinkedHashMap<Character,Integer> hash = new LinkedHashMap<>();
		for(int i=0;i<s.length();i++) {
			if(hash.containsKey(s.charAt(i))) {
				hash.put(s.charAt(i), hash.get(s.charAt(i))+1);
			}else  hash.put(s.charAt(i), 1);		 
		}
		for(char key:hash.keySet()) {
			int value = hash.get(key);
	        if(value==1) return key;
		}
		return 32;
    }
  • 运行结果:

题解中利用有序哈希表的想法写的代码如下:与我的区别主要有二:遍历字符串s的方式用的是s.toCharArray();map存储的键值对的意义不同(见解法二解释)

public char firstUniqChar(String s) {
        Map<Character, Boolean> dic = new LinkedHashMap<>();
        char[] sc = s.toCharArray();
        for(char c : sc)
            dic.put(c, !dic.containsKey(c));
        for(Map.Entry<Character, Boolean> d : dic.entrySet()){
           if(d.getValue()) return d.getKey();
        }
        return ' ';
    }

运行结果是:42%/55%

解法二

题解中用<k,v>存储<字符,boolean>,其中boolean表示:在插入当前字符时不存在此key则为true,存在此key为false,从而遍历哈希表时得到值为true的键。(此处作者用遍历sc保证了字符的顺序,所以不必用LinkedHashMap代替HashMap)

public char firstUniqChar(String s) {
        HashMap<Character, Boolean> dic = new HashMap<>();
        char[] sc = s.toCharArray();
        for(char c : sc)
            dic.put(c, !dic.containsKey(c));
        for(char c : sc)
            if(dic.get(c)) return c;
        return ' ';
    }

运行结果是:54%/58%

解法三

用数组代替哈希表,以字符的ASCII码为数组下标,对应存字符出现的次数。

public char firstUniqChar(String s) {
        int[] count = new int[256]; //这里的数组元素被初始化为0
        char[] chars = s.toCharArray();
        for(char c : chars)
            count[c]++;
        for(char c : chars){
            if(count[c] == 1)
                return c;
        }
        return ' ';
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值