zoukankan      html  css  js  c++  java
  • Easy | LeetCode 387. 字符串中的第一个唯一字符 | 哈希 | 哈希+队列

    387. 字符串中的第一个唯一字符

    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

    示例:

    s = "leetcode"
    返回 0
    
    s = "loveleetcode"
    返回 2
    

    提示:你可以假定该字符串只包含小写字母。

    解题思路

    方法一: 哈希表 + 两次遍历

    public int firstUniqChar(String s) {
        Map<Character, Integer> frequency = new HashMap<Character, Integer>();
        // 第一次遍历, 将所有元素使用哈希表计数
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            frequency.put(ch, frequency.getOrDefault(ch, 0) + 1);
        }
        // 第二次遍历, 根据哈希表的计数值返回第一个只出现一次的字符
        for (int i = 0; i < s.length(); ++i) {
            if (frequency.get(s.charAt(i)) == 1) {
                return i;
            }
        }
        return -1;
    }
    

    方法二: 哈希表存储索引

    这种思路和方法一类似, 不过存储时需要做改变, 在存储哈希表时, 如果某字符是第一次出现, 则将字符的索引作为Value存储, 如果不是第一个存储, 则将value修改为-1。

    然后第二次遍历时, 不遍历原字符串, 而是采用遍历哈希表的方式, 找到value不为-1的所有value的最小值。

    public int firstUniqChar(String s) {
        Map<Character, Integer> position = new HashMap<Character, Integer>();
        int n = s.length();
        for (int i = 0; i < n; ++i) {
            char ch = s.charAt(i);
            if (position.containsKey(ch)) {
                position.put(ch, -1);
            } else {
                position.put(ch, i);
            }
        }
        int first = n;
        for (Map.Entry<Character, Integer> entry : position.entrySet()) {
            int pos = entry.getValue();
            if (pos != -1 && pos < first) {
                first = pos;
            }
        }
        if (first == n) {
            first = -1;
        }
        return first;
    }
    

    方法三: 队列

    public int firstUniqChar(String s) {
        Map<Character, Integer> position = new HashMap<Character, Integer>();
        Queue<Pair> queue = new LinkedList<Pair>();
        int n = s.length();
        for (int i = 0; i < n; ++i) {
            char ch = s.charAt(i);
            if (!position.containsKey(ch)) {
                // 某字符第一个出现时, 在HashMap中记录出现的位置
                position.put(ch, i);
                // 并且将字符和出现的位置入队
                queue.offer(new Pair(ch, i));
            } else {
                // 如果这个字符不是第一次出现, 将其Value标记为-1
                position.put(ch, -1);
                // 然后将队列的队首的所有出现多次的元素出队。
                while (!queue.isEmpty() && position.get(queue.peek().ch) == -1) {
                    queue.poll();
                }
            }
        }
        // 返回队列的队首元素的下标 
        return queue.isEmpty() ? -1 : queue.poll().pos;
    }
    
    class Pair {
        char ch;
        int pos;
    
        Pair(char ch, int pos) {
            this.ch = ch;
            this.pos = pos;
        }
    }
    
  • 相关阅读:
    Oracle完全卸载
    Oracle数据库(64位) 及 PLSQL(64位)的组合安装【第一篇】
    Yii2 配置yii2redis扩展
    php 获取每个汉字的拼音首字母
    linux 安装memcacheq
    php在linux中执行外部命令
    比较两个日期的时间差精确到秒
    mysql 的 备份与还原
    php类中__get和__set的用法
    yii2.0 安装
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14457426.html
Copyright © 2011-2022 走看看