【快速刷题模板】-2分钟秒杀字符统计-只出现一次的字符串
2026/5/8 16:40:06 网站建设 项目流程

字符串-只出现一次的字符串

默写代码:

publicclassSolution{/** * @param str: str: the given string * @return: char: the first unique character in a given string */publiccharfirstUniqChar(Stringstr){// Write your code hereMap<Character,Integer>map=newHashMap<>();// 0if(str==null||str.length()==0)returnstr.charAt(0);// countfor(Characterc:str.toCharArray()){map.put(c,map.getOrDefault(c,0)+1);}for(inti=0;i<str.length();i++){charc=str.charAt(i);if(map.get(c)==1){returnc;}}returnstr.charAt(0);}}

为什么 Map<Character, Integer> map = new HashMap<>();用包装类

因为Java 泛型只支持引用类型,不支持基本类型。这是 Java 语言设计的硬性规定,与集合框架的实现机制直接相关。


核心原因:

  1. 泛型擦除机制
    Java 泛型是编译期语法糖,运行时会擦除类型信息变为Objectchar/int是基本类型,不属于Object子类,无法参与擦除转换。Character/Integer作为包装类,继承自Object,完全符合要求。

  2. 集合存储的是对象引用
    HashMap内部实现依赖Node<K,V>节点存储键值对,其字段类型是KV,只能是引用类型。基本类型没有引用概念。


编码便利性:自动装箱/拆箱

虽然必须用包装类,但 Java 5+ 的自动装箱机制让你几乎无感:

map.put('a',1);// 'a' 自动装箱为 Character,1 自动装箱为 Integercharc=map.keySet().iterator().next();// 自动拆箱intcount=map.get('a');// 自动拆箱

⚠️ 你代码的致命 Bug

if(str==null||str.length()==0)returnstr.charAt(0);// 空串时 charAt(0) 会抛异常!

应改为:

if(str==null||str.length()==0)return' ';// 或抛异常

效率优化:数组秒杀

这道题最优解是数组计数(ASCII 范围),比 HashMap 快 3-5 倍:

publiccharfirstUniqChar(Stringstr){if(str==null||str.length()==0)return' ';int[]count=newint[256];// ASCII 范围for(charc:str.toCharArray())count[c]++;for(charc:str.toCharArray())if(count[c]==1)returnc;return' ';}

记住:唯手熟尔,模板刻在骨子里才能秒。

2.// ASCII 范围为什么是256呢?

因为 8位二进制最多能表示256个不同数值(2^8 = 256),范围是0 ~ 255


详细解释:

  1. 标准 ASCII 码
    只定义了128个字符(0-127),包括字母、数字、控制符等。

  2. 扩展 ASCII 码
    早期系统为了容纳更多符号,把范围扩展到256(0-255),涵盖了拉丁字母、制表符等。

  3. 编程惯例
    在面试算法题中,题目默认字符串由可见字符组成,其 ASCII 值都在256范围内。用new int[256]100%覆盖所有可能性,且内存占用极小(仅 1KB)。

  4. Java char 类型
    Java 的char虽然是 16 位(Unicode),但本题涉及的字符都在 ASCII 子集内,所以用 256 的数组完全够用。


记住这个模板:

int[]cnt=newint[256];// 字符计数器标配

这是刷题肌肉记忆的一部分,唯手熟尔,直接刻进脑子里。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询