刷题
刷题不是为了刷题而是为了学到更多,所以特此详细解析每一道题。
问题
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
限制:
0 <= s 的长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1时间复杂度O(2n)利用HashMap
class Solution {
public char firstUniqChar(String s) {
if(s == " "){
return ' ';
}
HashMap<Character,Integer> tmp = new HashMap<>();
for(int i = 0;i < s.length();i++ ){
if( tmp.get(s.charAt(i)) == null){
tmp.put(s.charAt(i),0);
}
Integer t =tmp.get(s.charAt(i))+1;
tmp.put(s.charAt(i), t);
}
for(int i = 0;i < s.length();i++ ){
Integer t = tmp.get(s.charAt(i));
if(t == 1){
return s.charAt(i);
}
}
return ' ';
}
}
这个写的复杂了,可以优化成HashMap<Character,Boolean>,不需要知道字符有多少个
方法2O(n)使用LinkedHashMap
class Solution {
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 ' ';
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个方法的巧妙之处在于,将N个字符简化成不重复的m个字符,时间复杂度为O(n) + O(m),同时m <= n,这样就可以说时间复杂度是O(n)。
方法3O(n),桶排序的概念
大佬叫他用数组替换HashMap,但是我觉得这个玩意和桶排序异曲同工。
public class firstUniqChar {
public char firstUniqChar(String s) {
int[] count = new int[256];
char[] chars = s.toCharArray();
for(char c : chars)
count[c]++;
for(char c : chars){
if(count[c] == 1)
return c;
}
return ' ';
}
}
作者:ustcyyw
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50java-shi-yong-shu-zu-dai-ti-ha-xi-bi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个方法妙在使用了256个桶子(数组),ASCII是256个,所以用256个桶子,每一个字符放一个桶子里面,每放一次就数组加一,然后遍历两次,最好就是O(n),最坏就是O(2n)