LeetCode 387: 字符串中的第一个唯一字符 First Unique Character in a String
题目:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
案例:
s = "leetcode" 返回 0. s = "loveleetcode", 返回 2.
注意事项:您可以假定该字符串只包含小写字母。
Note: You may assume the string contain only lowercase letters.
解题思路:
很简单的题,无非就是对字符串的字母进行频率统计,找到出现频率为1 的字母索引。
借助哈希映射两次遍历完成。第一次遍历进行字母频率统计,Hash Map 的Key 为字母,Value 为出现频率。第二次遍历找到频率为 1 的字母索引返回即可。
不同于单词频率统计,字母一共只有 26 个,所以可以直接利用 ASii 码表里小写字母数值从 97~122,直接用 int 型数组映射。建立映射:索引为 小写字母的 ASii 码值,存储值为出现频率。
哈希映射解题:
Java:
class Solution { public int firstUniqChar(String s) { char[] chars = s.toCharArray();//转成 Char 数组 Map<Character, Integer> map = new HashMap<>(); for (Character c: chars) map.put(c, map.getOrDefault(c, 0) + 1);//频率统计 for (int i = 0; i < chars.length; i++) { if(map.get(chars[i])==1) return i;//找到词频为1的字母(只出现一次)返回其索引 } return -1; } }
Python:
class Solution: def firstUniqChar(self, s): count = collections.Counter(s)# 该函数就是Python基础库里词频统计的集成函数 index = 0 for ch in s: if count[ch] == 1: return index else: index += 1 return -1
数组映射解题:
Java:
class Solution { public int firstUniqChar(String s) { char[] chars = s.toCharArray(); int base = 97; int[] loc = new int[26]; for (char c:chars) loc[c - base] += 1; for (int i = 0; i < chars.length; i++) { if(loc[chars[i]-base]==1) return i; } return -1; } }
Python 基础数据结构里没有 char 型,强行使用chr(i)
转换,只会导致效率更低
字符串函数解题:
Java:
利用 Java 字符串集成操作函数解题,很巧妙,效率也很高。
其中:
indexOf(): 返回该元素第一次出现的索引,没有则返回 -1
lastIndex(): 返回该元素最后一次出现的索引,没有则返回 -1
class Solution { public int firstUniqChar(String s) { int res = s.length(); for (int i = 'a'; i <= 'z'; i++) { int firstIndex = s.indexOf((char)i); if (firstIndex == -1) continue; int lastIndex = s.lastIndexOf((char)i); if (firstIndex == lastIndex) {//两次索引值相同则证明该字母只出现一次 res = Math.min(firstIndex, res);//res 为只出现一次的字母中索引值最小的 } } return res == s.length() ? -1 : res; } }
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java描述设计模式(17):调停者模式
本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 在公司的日常安排中,通常划分多个部门,每个部门又会分为不同的小组,部门经理的一项核心工作就是协调部门小组之间的工作,例如开发小组,产品小组,小组的需求统一汇总到经理,经理统一安排和协调。 2、场景图解 3、代码实现 public class C01_InScene { public static void main(String[] args) { Manager manager = new Manager() ; EmployeeA employeeA = new EmployeeA("张三",manager) ; EmployeeB employeeB = new EmployeeB("李四",manager) ; employeeA.sendMsg(employeeA.name,"需要产品文档",employeeB); } } /** * 部门协调接口 */ interface Department { void coordinate (String userName,String msg,Em...
- 下一篇
线程池的初步认识(一)
线程池的初步认识(一) 一、定义 管理一组工作线程。 二、作用 可以限制应用程序中同一时刻运行的线程数; 可以应用在多线程服务器上。 三、好处 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗,比如内存; 提高响应速度。创建线程再到执行任务的额外时间,会延迟处理的请求; 提高线程的客观理性。通过线程池,实现对线程的统一分配,调优和监控;比如可以避免无线创建线程引起的OutOfMemoryError。 四、java 5 在 java.util.concurrent 中内置线程池 Excutors,返回对象为ThreadPoolExecutor,包含三种创建的方法: ExecutorService executorService1 = Executors.newSingleThreadExecutor(); ExecutorService executorService2 = Executors.newFixedThreadPool(10); ExecutorService executorService3 = Executors.newScheduledThreadPo...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8编译安装MySQL8.0.19