LeetCode - 387. 寻找字符串首个唯一字符

LeetCode - 387. First Unique Character in a String

Posted by zihengCat on 2019-09-09

前言

本文记录 LeetCode - 387. 字符串首个唯一字符(First Unique Character in a String) 问题。

问题描述

给出一枚字符串,请寻找字符串中第一个不重复字符,返回该字符在字符串中的索引下标。如果字符不存在,返回-1

输入: "leetcode"
输出: 0

注:示例 1

输入: "loveleetcode"
输出: 2

注:示例 2

注意:可以假定输入字符串仅包含英文小写字符。

问题解答

字符串问题,寻找字符串中第一个不重复字符。很容易想到的解题思路是:对于字符串中的每一个字符,再次遍历字符串判断该字符是否重复,无重复则返回字符索引下标。

public class Solution {
    public int firstUniqChar(String s) {
        if (s == null || s.length() == 0) {
            return -1;
        }
        char[] arr = s.toCharArray();
        for (int i = 0; i < arr.length; ++i) {
            if (findCharacter(arr[i], arr, i + 1, arr.length - 1) == -1 &&
                findCharacter(arr[i], arr, 0, i - 1) == -1) {
                return i;
            }
        }
        return -1;
    }
    private static int findCharacter(char c, char[] arr, int left, int right) {
        for (int i = left; i <= right; ++i) {
            if (arr[i] == c) {
                return i;
            }
        }
        return -1;
    }
}
/* EOF */

代码片段:寻找字符串首个唯一字符 - 暴力法

但是,多次遍历字符串的暴力算法效率不高:

  • 时间复杂度:$O(n^2)$
  • 空间复杂度:$O(1)$

另一种实现思路是:引入「有序哈希表」,存储字符串中每个字符的出现次数,只需遍历字符串一遍构建起哈希表,再查表即可得到结果。

  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$
import java.util.Map;
import java.util.LinkedHashMap;

public class Solution {
    public int firstUniqChar(String s) {
        if (s == null || s.length() == 0) {
            return -1;
        }
        Map<Character, Integer> map = new LinkedHashMap<Character, Integer>();
        char[] arr = s.toCharArray();
        for (int i = 0; i < arr.length; ++i) {
            map.put(arr[i],
                map.get(arr[i]) == null ? 1 : map.get(arr[i]) + 1
            );
        }
        for (Character c : map.keySet()) {
            if (map.get(c) == 1) {
                return s.indexOf(c);
            }
        }
        return -1;
    }
}
/* EOF */

代码片段:寻找字符串首个唯一字符 - 哈希表法

参考资料