算法的学习笔记—字符流中第一个不重复的字符(牛客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连支持一下,创造不易您们的支持是我的动力🤞

相关推荐
利刃大大3 小时前
【回溯+剪枝】找出所有子集的异或总和再求和 && 全排列Ⅱ
c++·算法·深度优先·剪枝
charlie1145141913 小时前
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(协议层封装)
c语言·驱动开发·单片机·学习·教程·oled
Rachela_z3 小时前
代码随想录算法训练营第十四天| 二叉树2
数据结构·算法
细嗅蔷薇@3 小时前
迪杰斯特拉(Dijkstra)算法
数据结构·算法
追求源于热爱!3 小时前
记5(一元逻辑回归+线性分类器+多元逻辑回归
算法·机器学习·逻辑回归
ElseWhereR3 小时前
C++ 写一个简单的加减法计算器
开发语言·c++·算法
马船长4 小时前
[BSidesCF 2020]Had a bad day1
学习
Smark.4 小时前
Gurobi基础语法之 addConstr, addConstrs, addQConstr, addMQConstr
算法
黄交大彭于晏4 小时前
三端回链增加截图功能
学习
S-X-S4 小时前
算法总结-数组/字符串
java·数据结构·算法