<LeetCode>剑指 Offer 50. 第一个只出现一次的字符

题目

第一个只出现一次的字符

在这里插入图片描述

思路1(HashMap)

利用HashMap,查询第一个只出现一次的字符,那么在第一轮循环字符串统计各个字符出现的次数,然后第二轮循环字符串,使用已经构建好的HashMap,当第一次找到出现次数为1时,返回该字符即可。

代码1

class Solution {
    public char firstUniqChar(String s) {
        HashMap<Character,Integer> hashmap=new HashMap<>();
        //char res=' ';
        for(int i=0;i<s.length();i++)
        {
            if(hashmap.containsKey(s.charAt(i)))
                hashmap.put(s.charAt(i),hashmap.get(s.charAt(i))+1);
            else
                hashmap.put(s.charAt(i),1);
        }

        for(int i=0;i<s.length();i++)
        {
            if(hashmap.get(s.charAt(i))==1)
                return s.charAt(i);
        }

        return ' ';
    }
}

在这里插入图片描述
时间复杂度比较高,应该是在containsKey那里花了比较多时间。


思路2 (26个小写字母)

由题目知,字符串中只含有小写字符,那么我们构建一个长度为26的字符数组,循环字符串一次用于统计次数,第二次循环字符串,找到数组中元素为1,即可根据下标返回该字符。

a-z对应97-122
因此创建数组arr[26],放置时根据字符(ch-97)即可将对应数组位置的值加1

代码2

class Solution {
    public char firstUniqChar(String s) {
        char arr[]=new char[26];
        //a-z对应于97-122
        for(int i=0;i<s.length();i++)
        {
            arr[s.charAt(i)-97]++;
        }

        for(int i=0;i<s.length();i++)
        {
            if(arr[s.charAt(i)-97]==1)
                return s.charAt(i);
        }

        return ' ';
    }
}

在这里插入图片描述

时间和空间都要优于方法1

思路3

还是利用HashMap,但是这次HashMap中的元素是CharacterBoolean,之所以是Boolean而不是Integer,是因为我们在意的是第一个只出现一次的元素,因此其它元素出现几次我们并不关心,因此我们只需要使用一个Boolean表示,true则表示其出现了一次,false则表示出现不止一次。

具体实现如下:
使用containsKey()函数,因为其返回值是Boolean类型,
一开始,元素不存在,我们第一次填入,因此Booleantrue
后面再填入相同的元素时,由于元素已经存在,因此Booleanfalse

hashmap.put(arr[i],!hashmap.containsKey(arr[i]));

仔细体会这一段代码,可以自己举例帮助理解,相信你一定能理解这段代码的巧妙之处^ ^

代码3

class Solution {
    public char firstUniqChar(String s) {
        HashMap<Character,Boolean> hashmap=new HashMap<>();

        char arr[]=s.toCharArray();

        for(int i=0;i<arr.length;i++)
        {
            hashmap.put(arr[i],!hashmap.containsKey(arr[i]));
        }

        for(int i=0;i<arr.length;i++)
        {
            if(hashmap.get(arr[i]))
                return arr[i];
        }

        return ' ';
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值