剑指Offer-36-第一个只出现一次的字符

题目

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

解析

预备知识

哈希表:存放键值对的容器。通过该容器,对于给定的key可以在O(1)的时间内访问到该键对应的值。实现原理其实来源于数组的随机访问的优势。对于数组,它是一种在物理和逻辑结构上都呈现为连续的数据结构,故而可以通过索引直接访问元素值。哈希表基于此,在内部定义了一个数组,同时又定义了一种哈希函数用于将key转化为数组的索引,这样我们就可以在O(1)的时间内访问到key对应的value值。

思路一

暴力解法,从头开始遍历字符串,每访问一个字符串,都将在其剩余的字符序列中考察是否出现第二次,若没有,则直接输出当前索引即可。
缺点:我们需要遍历一遍字符串O(n), 对于每一个字符又要遍历剩余字符序列是否出现第二次O(n),所以总复杂度为O(n^2)
优点:若第一次出现的字符串位置靠前,该方法可以快速找到目标字符

思路二

我们统计字符串中每个字符出现的次数,然后再遍历一遍字符串,判断其出现次数是否为1即可。
统计字符出现的次数可以利用哈希表,这样在判断出现次数为1时,可以直接通过字符获取到出现次数。
以上只需两次遍历,一次为了统计,一次为了判断,总复杂度为O(n)。
这就是典型的空间换时间的做法。

    public static int FirstNotRepeatingChar(String str) {
        if(str != null) {
            //因为字符串仅有字母,所以我们可以根据字母的ASCII码范围缩小存储空间
            int length = 'z' - 'A' + 1;
            int[] count = new int[length];
             for(int i = 0; i < str.length(); i++) {
                count[str.charAt(i) - 'A']++;
             }
             for(int i = 0; i < str.length(); i++) {
                 if(count[str.charAt(i) - 'A'] == 1) {
                     return i;
                 }
             }
        }
        return -1;
    }

总结

统计字符之类,数据种类少时,都可以尝试空间换时间的做法。

猜你喜欢

转载自blog.csdn.net/dawn_after_dark/article/details/81515467
今日推荐