每日一题-字符串 leetcode387

113 阅读2分钟

一、题目描述

二、题目思路

遍历字符串,存储字符以及出现次数,再次遍历字符串,判断字符的出现次数是否为1,是1则返回(字符首次只出现一次)。字符串的尺寸使用的是length()函数,集合的尺寸使用的是size()函数,数组的尺寸使用的是length变量。

三、提交代码

class Solution {
    public int firstUniqChar(String s) {
        HashMap<Character,Integer> hashMap = new HashMap<>();
        for(int i =0;i<s.length();i++){
            hashMap.put(s.charAt(i),hashMap.getOrDefault(s.charAt(i),0)+1);
        }
        for(int j =0;j<s.length();j++){
            if(hashMap.get(s.charAt(j)) == 1){
                return j;
            }
        }
        return -1;
    }
}

四、存在问题

只想到利用哈希表存储字符及出现次数

没考虑到二次遍历返回索引即可

五、其他优解

class Solution {
    public int firstUniqChar(String s) {
        if(s.length()<=26){
            int[] charNum = new int[26];
            char[] chars = s.toCharArray();
            for(int i=0;i<s.length();i++){
                charNum[chars[i]-'a']++;
            }
            for(int j =0;j<s.length();j++){
                if(charNum[chars[j] - 'a'] ==1){
                    return j;
                }
            }
            return -1;
        }
        int index =-1;
        for(char c = 'a';c<='z';c++){
            int beginIndex = s.indexOf(c);
            if(beginIndex != -1 && beginIndex == s.lastIndexOf(c)){
                index = (index == -1||index>beginIndex)? beginIndex :index ; 
            }
        }
        return index;
    }
}

六、优解思路

  1. 根据字符串长度分解成两种情况进行处理,当字符串长度小于等于26时,只需要遍历a-z字母集合,找到出现次数为1的字符即可

String.toCharArray() 函数可以将字符串所有字符转换为字符数组进行存储

单次出现的字符并不一定是按照字母顺序排列,因此,第二次for()循环中的判断条件是 if(charNum[chars[i]-'a']) ==1

  1. 对于字符串长度大于26的情况,首先找到每个字符的索引位置,如果最后一次的索引位置等于首次找到的索引位置,则暂存在结果中,之后遇到类似情况,判断暂存的结果是否大于新的候选结果值(保证单次字符首次出现),是则更新,否则继续,直至结束