第4天----找出第一个只出现一次的字符(桶计数法/4种思路讲解)

news2024/11/18 5:47:27

题目描述

给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符。如果没有,输出 no

输入格式

一个字符串,长度小于 1100。

输出格式

输出第一个仅出现一次的字符,若没有则输出 no

输入输出样例

输入 #1复制

abc

输出 #1复制

c

输入 #2复制

aabbcc

输出 #2复制

no

方法一: 

二维数组+桶计数法

        这是我最原始的想法,比较直接,但稍显复杂:

1.对输入的字符串的每个字符进行分析,分别记录每个字符首次出现的顺序和出现的次数,分别存储在二维数组b[ ][ ]中;

2.然后遍历二维数组b[ ][ ],将出现1次以上的字符所对应的次数赋值为0,只剩下出现一次的字符;

3.然后利用min先记录其中一个只出现一次的字符,然后进行循环查找,找到最先出现的字符的编号(最小编号)并赋值给min;

4.最后利用循环查找,找到min所对应的编号的编号(0-25取一值,来代表对应字符),再输出即可

代码如下: 

#include<iostream>

using namespace std;

int main(void)
{
    char a[1101];
    int b[26][2] = {0,0};
   
    cin >> a;
    int j = 1; 
    int n = sizeof(a) / sizeof(a[0]);
        for (int i = 1; i <= n; i++)
        {
            b[a[i-1]-97][1]++;
            
            if (b[a[i - 1] - 97][0] == 0) {

                 b[a[i - 1] - 97][0] = j++; 
             
            }
                  
        }
    int min=26;
    for (int i = 0; i < 26; i++)
    {
        
            if (b[i][1] == 1)
            {
                min = b[i][0];
               
            }
            else {
                b[i][0] = 0;
                b[i][1] = 0;
            }     
    }
    for (int i = 0; i < 26; i++)
    {
        if (b[i][0] < min && b[i][0]!=0) min = b[i][0];
        else continue;
    }

    for (int i = 0; i < 26; i++)
    {
        if (min == b[i][0]) {
        cout << (char)(i + 97);
         exit(EXIT_SUCCESS);
        }
           

    }

    cout << "no";
    return 0;
}

方法二:

一维数组+桶计数法

        由于方法一过于复杂,所以我想着能不能用更加简单的方法来完成这道题。方法二非常简单,直接查找,没有任何复杂的操作。

1.我们枚举输入的字符串str每个字符(0到 n−1),如果出现就标记visit[str[i] - 'a']true,然后如果枚举到一个字符并且他的visittrue(被访问过),就把他的flag标记为true(标记为不可以)

2.然后再次枚举每个字符,如果这个字符的flagfalse(只被访问过 1 次)

那就直接输出,然后 return 0(这样就保证了是第一个)

如果没有 flag 为 false 的,就输出 no

代码如下:

#include<iostream>
using namespace std;
bool visit[30];
bool flag[30];
int main()
{
	string str;
	cin >> str;
	for(int i = 0; i < str.size(); i++)
	{
		if(visit[str[i] - 'a'])
		{
			flag[str[i] - 'a'] = true;
		}
		visit[str[i] - 'a'] = true;
	}
	for(int i = 0; i < str.size(); i++)
	{
		if(!flag[str[i] - 'a'])
		{
			cout << str[i];
			return 0;
		}
	}
	cout << "no";
	return 0;
}

        这个方法的好处在于规避了复杂的计算方法,用更为直接的手段进行解题,整体来看没有任何多余的代码,强烈推荐!

方法三:

map+桶计数法

        题目中给的是字符串,怎么用整形表示?我们想一想,有哪个数据结构可以实现不同数据类型的映射?答案是: STL 库中的 map !

        介于大家可能并不是十分了解 map ,这里简单介绍一下:我们可以把 map 看作一个可以存储任何数据形式的动态数组(也就是下标不做限制的数组啦),它的定义方式为:

map <存储进去的类型,用来表示数据的类型> 名称;

        举个例子,在本题中我们可以建立一个 char 类型与 int 类型相互映射(照应)的 map 来进行桶排序,即定义过程为

map <char,int> a;

        最后是闪亮的代码啦!

#include <map> //使用 map 要调用 map 库
#include <iostream>
#include <string>

using namespace std;

map <char,int> a;
string s;

int main()
{
	cin>>s;
	
	for(int i = 0; i <s.size(); i++) //注意字符串从 0 开始
	{
		a[s[i]]++;//将所有字符出现的次数都算进去
	}
	for(int i = 0; i <s.size(); i++)
	{
		if(a[s[i]] == 1)//第一个为1的字符必定是目标字符
		{
			cout<<s[i];
			return 0;
		}
	}
	cout<<"no";
	
	return 0;
}

方法四:

桶计数法:

        此方法和方法3有异曲同工之妙,先按照字符的出现顺序遍历,将出现的次数和出现的顺序绑定起来,利用桶记录次数;然后直接从第一个字符开始遍历,判断是否满足条件即可;

        可能会有人问:最先遍历出的符合要求字符一定是目标字符吗?答案是肯定的。

        因为我们已经利用桶将字符的出现顺序和出现的次数绑定起来了,再次遍历的时候每个字符出现的次数都是已知的,而出现的顺序也是不变的,所以相当于给我们给定一行特定顺序的字符,例如:abcdefghijklmnopqrstuvwxyzabc;现在我们已知第一个出现一次的字符是'd',然后从'a'开始遍历,判断每个字符出现的次数,a出现两次,不符合条件;继续判断b...;直到找到符合条件的字符为止,找到后立刻输出并返回;否则输出no;

#include<bits/stdc++.h>
using namespace std;
int a[30];
int main()
{
	string st;
	cin>>st;
	for(int i=0;i<st.size();i++)//这个字母出现了几次
	{
		a[st[i]-'a']++;//转化成较小数字
	}
	for(int i=0;i<st.size();i++)
	{
		if(a[st[i]-'a']==1)//如果出现了一次
		{
			cout<<st[i];
			return 0;//直接退出程序
		}
	}
	cout<<"no";
	return 0;
}

        我一直认为刷题不仅仅是刷题,更重要的是还是要学会思考,解决问题的方式有很多,但如何寻找适合自己的方法尤为重要。如果你有好的方法和建议,请在评论区留言,我们一起学习、进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/905944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙/Android上最大的毒瘤:快应用服务

鸿蒙/Android上最大的毒瘤&#xff1a;快应用服务 2023.3.22版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、什么是快应用&#xff1f; “快应用” 是安卓厂&#xff08;华&#xff0c;米&#xff0c;O、V、魅族、努、联、加&#xf…

消息中间件的选择:RabbitMQ是一个明智的选择

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; MQ&#xff08;Message Queue&#xff09; MQ&#xff08;消息队列&#xff09;是一种用于在应用程序之间进行异步通信的技术&#xff1b;允许应用程序通过发送和接收…

[虚幻引擎] DTGlobalVariable 插件说明,蓝图全局变量访问,设置, Get, Set。

本插件可以在蓝图或者UMG中直接访问指定的全局变量值&#xff0c;方便编写。 支持Bool&#xff0c;Byte&#xff0c;Int&#xff0c;Int64&#xff0c;Float&#xff0c;Name&#xff0c;String&#xff0c;Text&#xff0c;Vector&#xff0c;Rotator&#xff0c;Transform&am…

【Linux网络】网络编程套接字 -- 基于socket实现一个简单UDP网络程序

认识端口号网络字节序处理字节序函数 htonl、htons、ntohl、ntohs socketsocket编程接口sockaddr结构结尾实现UDP程序的socket接口使用解析socket处理 IP 地址的函数初始化sockaddr_inbindrecvfromsendto 实现一个简单的UDP网络程序封装服务器相关代码封装客户端相关代码实验结…

TE-L-Tyrosine (FET-precursor),合成蛋白质的必需成分之一,L-Tyrosine

试剂简介&#xff1a;TE-L-Tyrosine (FET-precursor)&#xff0c;L-Tyrosine是一种氨基酸&#xff0c;它是蛋白质合成的必需成分之一。除了在蛋白质合成中的重要作用外&#xff0c;L-Tyrosine还具有多种生理功能。它是肾上腺素、去甲肾上腺素、甲状腺激素等重要激素的前体物质&…

短视频矩阵系统源码|开发者步骤

一、为了开发和部署短视频矩阵系统&#xff0c;首先需要进行以下步骤&#xff1a; 1. 系统设计与开发&#xff1a;根据需求&#xff0c;进行系统架构设计&#xff0c;并选择合适的技术栈进行开发。这可能涉及到前端开发、后端开发、数据库设计等工作。 2. 实现核心功能&#…

AIGC与软件测试的融合

一、ChatGPT与AIGC 生成式人工智能——AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;&#xff0c;是指基于生成对抗网络、大型预训练模型等人工智能的技术方法&#xff0c;通过已有数据的学习和识别&#xff0c;以适当的泛化能力生成相关内容的技术。…

MySQL运行时的可观测性

1.说在前面的话 2.安装employees测试库 3.观测SQL运行状态 3.1 观测SQL运行时的内存消耗3.2 观测SQL运行时的其他开销3.3 观测SQL运行进度 感知SQL运行时的状态 1. 说在前面的话 在MySQL里&#xff0c;一条SQL运行时产生多少磁盘I/O&#xff0c;占用多少内存&#xff0c;是否…

Ctfshow web入门 命令执行RCE篇 web29-web77 与 web118-web124 详细题解 全

Ctfshow 命令执行 web29 pregmatch是正则匹配函数&#xff0c;匹配是否包含flag&#xff0c;if(!preg_match("/flag/i", $c))&#xff0c;/i忽略大小写 可以利用system来间接执行系统命令 flag采用f*绕过&#xff0c;或者mv fl?g.php 1.txt修改文件名&#xff0c…

一文彻底理解时间复杂度和空间复杂度(附实例)

目录 1 PNP&#xff1f;2 时间复杂度2.1 常数阶复杂度2.2 对数阶复杂度2.3 线性阶复杂度2.4 平方阶复杂度2.5 指数阶复杂度2.6 总结 3 空间复杂度 1 PNP&#xff1f; P类问题(Polynomial)指在多项式时间内能求解的问题&#xff1b;NP类问题(Non-Deterministic Polynomial)指在…

数据中心UPS监控,不服不行!

UPS作为关键的电力保障设备&#xff0c;它在电力中断或波动的情况下&#xff0c;为电子设备提供稳定的备用电源&#xff0c;以防止数据丢失、设备损坏或生产中断。 通过远程监控、电池健康检测、负载管理、警报通知等功能&#xff0c;UPS监控确保了系统的高效运行和可靠性。同时…

Windows下安装tomcat无法启动问题汇总和解决

tomcat在初学的时候安装总是出现各种问题&#xff0c;最近重新安装了一次&#xff0c;居然也被一些小问题导致无法启动了&#xff0c;特此写下这篇文章&#xff0c;希望能帮助到大家 导致tomcat启动失败原因 1、未配置tomcat环境变量: CATALINA_HOME&#xff1b;然后path环境…

扭矩张力控制和速度张力控制详细介绍

张力控制的开环和闭环相关算法介绍,请查看下面文章链接: PLC张力控制(开环闭环算法分析)_张力控制plc程序实例_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算法,关于绕…

LeetCode(力扣)404. 左叶子之和Python

LeetCode404. 左叶子之和 题目链接代码 题目链接 左叶子之和 代码 递归 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right …

【JavaEE进阶】SpringMVC

文章目录 一. 简单认识SpringMVC1. 什么是SpringMVC?2. SpringMVC与MVC的关系 二. SpringMVC1. SpringMVC创建和连接2. SpringMVC的简单使用2.1 RequestMapping 注解介绍2.2 RequestMapping支持的请求类型2.3 GetMapping 和 PostMapping 3. 获取参数3.1 传递单个参数3.2 传递对…

2023年跑步耳机性价比最高的都在这里了!不容错过

你还在为如何选择合适的跑步耳机而困扰吗&#xff1f;身为一个常年的跑步的我&#xff0c;在选择运动耳机的时候我会从价格、性能、舒适度、耐用性等多个方面去进行了比较&#xff0c;这样才能够找到最适合自己的跑步耳机。那么下面我就给大家推荐几款具有性价比的跑步耳机&…

项目管理工具,让项目团队更高效

随着项目管理的发展&#xff0c;出现个各种各样的项目管理工具&#xff0c;帮助项目团队提高项目管理的效率和质量&#xff0c;降低成本和风险&#xff0c;增强团队的协作和沟通效率&#xff0c;实现项目的成功实施和持续发展。 1、项目计划是项目管理中重要的一环 在传统的…

4.react useContext使用与常见问题

1. 在函数组件实现跨组件通信的方式 2. 注册Context将value传递给子组件let MyContext React.createContext(默认值); <MyContext.Provider value{} > let value useContext(MyContext)<!DOCTYPE html> <html lang"en"><head><meta cha…

【正点原子STM32连载】第十五章 窗口看门狗实验 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第十…

认识Mybatis并实现增删查改

目录 一.Mybatis特性 二.常见持久层技术的比较 三.搭建Mybaits环境 四.使用Mybatis 五.通过Mybatis实现增删改 六.实现数据库的查询操作 一.Mybatis特性 定制化SQL&#xff1a;MyBatis允许开发人员编写、优化和管理自定义的SQL语句&#xff0c;可以满足复杂查询和存储过程等…