算法的学习笔记—字符流中第一个不重复的字符(牛客JZ75)

😀前言

在编程面试和实际项目中,处理字符流并找到其中第一个不重复的字符是一个常见的挑战。本文将详细介绍如何利用 Java 来实现这一功能,并提供一个有效的解决方案。

🏠个人主页:尘觉主页

文章目录

😀字符流中第一个不重复的字符

牛客网

😊问题描述

我们需要设计一个函数来处理字符流,目标是找到流中第一个只出现一次的字符。例如:

  • 当字符流中读到 "go" 时,第一个不重复的字符是 "g"。
  • 当读到 "google" 时,第一个不重复的字符变成了 "l"。

我们的任务是实现两个函数:

  • Insert(char ch):用于将字符插入到字符流中。
  • FirstAppearingOnce():返回字符流中第一个只出现一次的字符。如果没有,返回 #

string caseout = "";

1.读入测试用例字符串casein

2.如果对应语言有Init()函数的话,执行Init() 函数

3.循环遍历字符串里的每一个字符ch {

Insert(ch);

caseout += FirstAppearingOnce()

}

\2. 输出caseout,进行比较。

🤔示例1

输入:"google"

返回值:"ggg#ll"

🤔示例2

输入:"abcdee"

返回值:"aaaaaa"

🥰解题思路

解决这个问题的一种有效方法是结合使用统计数组和队列来跟踪字符的出现次数和顺序。

  1. 统计字符出现次数
    由于字符都是 ASCII 码范围内的字符,我们可以使用一个大小为 128 的整型数组来记录每个字符出现的次数。通过将字符的 ASCII 码作为索引,可以快速地更新和查询每个字符的出现次数。
  2. 维护字符顺序
    使用队列来保存字符流中的字符顺序。每次插入新字符时,我们将其添加到队列中。同时,我们通过检查队列头部的字符来找出第一个出现一次的字符。如果队列头部的字符不再是只出现一次,我们就将其从队列中移除。
  3. 返回第一个不重复字符
    FirstAppearingOnce() 函数负责返回队列头部的字符。如果队列为空,则说明没有不重复的字符,返回 #

😁代码实现

java 复制代码
import java.util.LinkedList;
import java.util.Queue;

public class FirstUniqueCharInStream {

    // 数组用于记录每个字符的出现次数
    private int[] cnts = new int[128];
    // 队列用于维护字符的顺序
    private Queue<Character> queue = new LinkedList<>();

    // 将字符插入到字符流中
    public void Insert(char ch) {
        cnts[ch]++;
        queue.add(ch);
        // 移除队列头部的非唯一字符
        while (!queue.isEmpty() && cnts[queue.peek()] > 1) {
            queue.poll();
        }
    }

    // 返回字符流中第一个只出现一次的字符
    public char FirstAppearingOnce() {
        return queue.isEmpty() ? '#' : queue.peek();
    }

    public static void main(String[] args) {
        FirstUniqueCharInStream stream = new FirstUniqueCharInStream();
        String testString = "google";
        StringBuilder result = new StringBuilder();
        for (char ch : testString.toCharArray()) {
            stream.Insert(ch);
            result.append(stream.FirstAppearingOnce());
        }
        System.out.println(result.toString()); // 输出 "ggg#ll"
    }
}

💝代码详解

  1. cnts 数组:用于记录每个字符的出现次数。因为 ASCII 码范围是 0-127,所以我们使用一个大小为 128 的数组。
  2. queue 队列:用于保存字符的顺序,确保我们能快速找到第一个不重复的字符。
  3. Insert 函数 :每次插入新字符时,更新 cnts 数组,并将字符添加到队列中。如果队列头部的字符不再唯一,则从队列中移除。
  4. FirstAppearingOnce 函数 :返回队列头部的字符,或在队列为空时返回 #

💝复杂度分析

  • 时间复杂度:每次插入和查找操作的时间复杂度均为 O(1),因此整体时间复杂度为 O(n)。
  • 空间复杂度:我们使用了一个大小为 128 的数组和一个队列,空间复杂度为 O(n)。

😄总结

通过使用统计数组和队列的组合,我们能够高效地处理字符流并找到第一个不重复的字符。这种方法在字符流处理中表现优异,适用于需要实时处理数据流的场景。如果你在编码面试中遇到类似问题,不妨试试这个解决方案。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁

希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻

如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

相关推荐
Y3174297 分钟前
Python Day23 学习
python·学习
song_ly0011 小时前
深入理解软件测试覆盖率:从概念到实践
笔记·学习·测试
DIY机器人工房1 小时前
[6-2] 定时器定时中断&定时器外部时钟 江协科技学习笔记(41个知识点)
笔记·stm32·单片机·学习·江协科技
海尔辛2 小时前
学习黑客5 分钟小白弄懂Windows Desktop GUI
windows·学习
?abc!3 小时前
缓存(5):常见 缓存数据淘汰算法/缓存清空策略
java·算法·缓存
BioRunYiXue3 小时前
一文了解氨基酸的分类、代谢和应用
人工智能·深度学习·算法·机器学习·分类·数据挖掘·代谢组学
DanB243 小时前
Java笔记4
java·开发语言·笔记
烟雨迷4 小时前
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
linux·服务器·学习·编辑器·vim
@十八子德月生4 小时前
8天Python从入门到精通【itheima】-1~5
大数据·开发语言·python·学习
jiunian_cn4 小时前
【c++】异常详解
java·开发语言·数据结构·c++·算法·visual studio