[2021校招必看之Java版《剑指offer》-54] 字符流中第一个不重复的字符

文章目录

  • 1、题目描述
  • 2、解题思路
  • 3、解题代码
  • 4、解题心得

1、题目描述

  【JZ54】请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
  知识点:哈希,队列
  难度:☆

2、解题思路

  如果我要从一个字符串中寻找是否存在某个字符,可以使用Set、Map等这些数据结构的contains方法。
  题目要求的是“第一个”、“只出现一次”的字符,需要满足两个条件。
  综上,需要一个哈希map和一个队列来实现。
  具体步骤:
  1、初始化一个HashMap和一个Queue
  2、插入字符时,如果不存在于HashMap中,则键值对为{ch:1},同时入队;如果已经存在,则map的键值对为{ch:getKey(ch)+1},不入队。
  3、获取第一个不重复字符时,如果map没有一个元素,返回#;队列出队一个字符,判断这个字符在map中的value是否为1,若是,则返回这个字符,若不是,则队列抛弃这个字符,重复操作。

3、解题代码

package pers.klb.jzoffer.medium;

import java.util.*;

/**
 * @program: JzOffer2021
 * @description: 字符流中第一个不重复的字符
 * @author: Meumax
 * @create: 2020-06-20 23:10
 **/
public class NonRepeatingChar {
     

    private Map<Character, Integer> map = new HashMap<>();
    private Queue<Character> queue = new LinkedList<>();

    //Insert one char from stringstream
    public void Insert(char ch) {
     
        if (map.containsKey(ch)) {
     
            // 如果已经存在,就重复数加一
            map.put(ch, map.get(ch) + 1);
        } else {
     
            // 第一次出现
            map.put(ch, 1);
            queue.add(ch);
        }
    }

    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce() {
     

        // 如果没有一个字符是只出现一次的,就返回 #
        if (!map.containsValue(1)) {
     
            return '#';
        }

        // 判断队列的第一个元素是否在后来又重复过
        while (map.get(queue.peek()) > 1) {
     
            queue.remove();
        }

        return queue.peek();
    }
}

4、解题心得

  本题容易让人第一反应是遍历所有的字符,但从题目描述的“第一个”、“只出现一次”关键语句可以推断出利用数据结构HashMap和队列Queue。
  以后遇到类似题型,要仔细读取题目的关键词,在不限制API的情况下,能用API就用API。

你可能感兴趣的:(剑指offer(Java语言),队列,数据结构,leetcode,哈希表,剑指offer)