算法的学习笔记—(牛客JZ50)

😀前言

在处理字符串时,寻找第一个只出现一次的字符是一项常见的任务。本文将探讨几种有效的解法,包括使用 HashMap 和位集(BitSet)。

🏠个人主页:尘觉主页

文章目录

🥰第一个只出现一次的字符位置

😇题目链接

牛客网

🤔题目描述

在一个字符串中找到第一个只出现一次的字符,并返回它的位置。字符串只包含 ASCII 码字符。

复制代码
Input: abacc
Output: b

💖解题思路

方法一:使用 HashMap

最直观的方法是使用 HashMap 来统计每个字符的出现次数。具体步骤如下:

  1. 遍历字符串,将字符作为键,出现次数作为值存入 HashMap。
  2. 再次遍历字符串,查找第一个出现次数为 1 的字符,返回其位置。

示例代码如下:

java 复制代码
public int FirstNotRepeatingChar(String str) {
    // 创建一个 HashMap,用于统计每个字符的出现次数
    Map<Character, Integer> countMap = new HashMap<>();
    
    // 遍历字符串,将字符作为键,出现次数作为值存入 HashMap
    for (char c : str.toCharArray()) {
        countMap.put(c, countMap.getOrDefault(c, 0) + 1);
    }
    
    // 再次遍历字符串,查找第一个出现次数为 1 的字符
    for (int i = 0; i < str.length(); i++) {
        if (countMap.get(str.charAt(i)) == 1) {
            // 返回该字符的位置
            return i;
        }
    }
    
    // 如果没有找到,返回 -1
    return -1;
}

以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。

方法二:使用整型数组

考虑到 ASCII 码字符有限,可以使用长度为 128 的整型数组代替 HashMap,来记录每个字符的出现次数。实现方法与上面类似,但效率更高。

java 复制代码
public int FirstNotRepeatingChar(String str) {
    // 创建一个长度为 128 的整型数组,用于统计字符出现次数
    int[] cnts = new int[128];
    
    // 遍历字符串,统计每个字符的出现次数
    for (int i = 0; i < str.length(); i++) {
        cnts[str.charAt(i)]++;
    }
    
    // 再次遍历字符串,查找第一个出现次数为 1 的字符
    for (int i = 0; i < str.length(); i++) {
        if (cnts[str.charAt(i)] == 1) {
            // 返回该字符的位置
            return i;
        }
    }
    
    // 如果没有找到,返回 -1
    return -1;
}

方法三:使用位集(BitSet)

为了进一步优化空间复杂度,可以使用 BitSet 来存储每个字符的状态,分为三种情况:未出现(0)、出现一次(1)和出现多次(2)。通过两个 BitSet,可以高效地统计字符的出现情况。

java 复制代码
public int FirstNotRepeatingChar2(String str) {
    // 创建两个 BitSet,用于记录字符的状态
    BitSet bs1 = new BitSet(128); // 用于记录字符出现一次
    BitSet bs2 = new BitSet(128); // 用于记录字符出现多次
    
    // 遍历字符串,更新字符的状态
    for (char c : str.toCharArray()) {
        if (!bs1.get(c) && !bs2.get(c)) {
            // 状态 0 -> 1(首次出现)
            bs1.set(c);
        } else if (bs1.get(c) && !bs2.get(c)) {
            // 状态 1 -> 2(再次出现)
            bs2.set(c);
        }
    }
    
    // 再次遍历字符串,查找第一个状态为 1 的字符
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        if (bs1.get(c) && !bs2.get(c)) { // 状态 1
            // 返回该字符的位置
            return i;
        }
    }
    
    // 如果没有找到,返回 -1
    return -1;
}

😄总结

本文介绍了三种方法来找到字符串中第一个只出现一次的字符。通过不同的数据结构和算法,解决方案的效率和空间复杂度各有不同。选择合适的方法取决于具体需求和数据规模。

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

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

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

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

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

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

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

相关推荐
黄金龙PLUS1 小时前
5个1024比特大状态置换算法的设计与分析
算法·网络安全·密码学·哈希算法·同态加密
心中有你02141 小时前
C语言埃氏筛法(素数筛选)
c语言·数据结构·算法
Omics Pro2 小时前
Cell封面|衰老生物学开源AI工具包
数据库·人工智能·算法·机器学习·自然语言处理
user_admin_god2 小时前
第 10 篇:拼上下文与生成——预算、边界与防幻觉
java·人工智能·spring boot·语言模型
用户3126874877202 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java
天天被压力3 小时前
【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #02】涨停跌停与特色股池:5类股池接口一次拉全
java·人工智能·python
斯维赤3 小时前
从 @Tool 到 Agent 流水线:LangChain4j 进阶教学,一个库打全套
java·后端
SimonKing3 小时前
SSE项目`nexus-sse`持续优化,不一样的视觉效果
java·后端·程序员
斑鸠喳喳3 小时前
读写锁模式 Read-Write Lock
java·后端
信誓旦旦的程序猿4 小时前
【Python 量化取数指南 #09】Python 拿港股通数据:港股通成交与港股财报实测
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据api