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

img

😀前言
在编程面试和实际项目中,处理字符流并找到其中第一个不重复的字符是一个常见的挑战。本文将详细介绍如何利用 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() 函数负责返回队列头部的字符。如果队列为空,则说明没有不重复的字符,返回 #

😁代码实现

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连支持一下,创造不易您们的支持是我的动力🤞

img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值