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

server/2024/10/23 2:24:22/

在这里插入图片描述

img

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

🏠个人主页:尘觉主页

文章目录

  • 🥰第一个只出现一次的字符位置
    • 😇题目链接
    • 🤔题目描述
    • 💖解题思路
      • 方法一:使用 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<>();// 遍历字符串,将字符作为键,出现次数作为值存入 HashMapfor (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;}}// 如果没有找到,返回 -1return -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;}}// 如果没有找到,返回 -1return -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;}}// 如果没有找到,返回 -1return -1;
}

😄总结

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

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

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

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

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

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

img


http://www.ppmy.cn/server/134048.html

相关文章

来个Oracle一键检查

启停、切换、升级、网络改造等场景下&#xff0c;需要对数据库有些基本检查操作&#xff0c;确认当前是否运行正常&#xff0c;主打一个简单和一键搞定。 #!/bin/bash## 实例个数 告警日志 实例状态 会话 活动会话 锁 集群状态 服务状态 磁盘空间 侦听日志 ## linux vmstat 2 …

截止10月19日,复盘秋招23场面试(三)每一场面试的核心问题和内容

1OPPO提前批一面 这份文件是一次面试的转写记录&#xff0c;面试的参与者是求职者面试者和OPPO的面试官。以下是面试的核心内容&#xff1a; 面试开始&#xff1a; 面试官和求职者进行了简单的问候&#xff0c;并确认了可以听到对方的声音。 自我介绍&#xff1a; 面试者介绍…

算法的学习笔记—数组中的逆序对(牛客JZ51)

&#x1f600;前言 在算法和数据结构领域&#xff0c;"逆序对"是一个经典问题。它在数组中两个数字之间定义&#xff0c;若前面的数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。我们要做的就是&#xff0c;给定一个数组&#xff0c;找出数组中所有的逆…

Vue的响应式原理

Vue.js 是一个流行的前端框架&#xff0c;它的响应式系统是其核心特性之一&#xff0c;能够有效地处理数据变化并自动更新视图。在这篇文章中&#xff0c;我们将探讨 Vue 的响应式原理&#xff0c;包括其实现方式、关键概念以及性能优化。 1. 响应式原理概述 Vue 的响应式原理…

vue3 解决背景图与窗口留有间隙的问题

需要实现一个登录界面&#xff0c;login.vue的代码如下&#xff1a; <script> import { ref } from vue;export default {setup() {return {};}, }; </script><template><div id"login-container" class"login-container"><di…

软考(网工)——局域网和城域网

文章目录 &#x1f550;局域网基础1️⃣局域网和城域网体系架构 IEEE&#xff08;负责链路层&#xff09;2️⃣局域网拓扑结构 &#x1f551;CSMA/CD1️⃣CSMA/CD2️⃣CSMA/CD三种监听算法3️⃣冲突检测原理 &#x1f552;二进制指数退避算法1️⃣ 二进制指数退避算法 &#x1…

Linux--firewalld服务

firewalld服务 firewalld 介绍 firewalld是CentOS 7.0新推出的管理netfilter的用户空间软件工具 firewalld是配置和监控防火墙规则的系统守护进程。可以实iptables,ip6tables,ebtables的功能 firewalld服务由firewalld包提供 firewalld支持划分区域zone,每个zone可以设置独立…

【C++】— 一篇文章让你认识STL

文章目录 &#x1f335;1.什么是STL&#xff1f;&#x1f335;2.STL的版本&#x1f335;3.STL的六大组件&#x1f335;4.STL的重要性&#x1f335;5. 如何学习STL&#x1f335;6. 学习STL的三种境界 &#x1f335;1.什么是STL&#xff1f; STL是Standard Template Library的简称…