剑指Offer面试题:30.第一个只出现一次的字符
一、题目:第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出'b'。要求时间复杂度为O(n)。
最直观的想法是从头开始扫描这个字符串中的每个字符。当访问到某字符时拿这个字符和后面的每个字符相比较,如果在后面没有发现重复的字符,则该字符就是只出现一次的字符。如果字符串有n个字符,每个字符可能与后面的O(n)个字符相比较,因此这种思路的时间复杂度是O(n2),但是不满足要求。
二、解题思路:以空间换时间
为了解决这个问题,我们可以定义一个哈希表(外部空间),其键值(Key)是字符,而值(Value)是该字符出现的次数。
同时我们还需要从头开始扫描字符串两次:
(1)第一次扫描字符串时,每扫描到一个字符就在哈希表的对应项中把次数加1。(时间效率O(n))
(2)第二次扫描时,每扫描到一个字符就能从哈希表中得到该字符出现的次数。这样第一个只出现一次的字符就是符合要求的输出。(时间效率O(n))
这样算起来,总的时间复杂度仍然是O(n),满足了题目要求,擦一擦汗,感叹:这*装得真有点技术!

装完了B,开始将这个想法实现为代码:
public static char FirstNotRepeatingChar(string str)
{
if(string.IsNullOrEmpty(str))
{
return '\0';
} char[] array = str.ToCharArray();
const int size = ;
// 借助数组来模拟哈希表,只用1K的空间消耗
uint[] hastTable = new uint[size];
// 初始化数组
for (int i = ; i < size; i++)
{
hastTable[i] = ;
} for (int i = ; i < array.Length; i++)
{
hastTable[array[i]]++;
} for (int i = ; i < array.Length; i++)
{
if (hastTable[array[i]] == )
{
return array[i];
}
} return '\0';
}
PS:字符(char)是一个长度为8的数据类型,因此总共有256种可能。(在C#中char则是长度为16位也就是2个字节)这里我们只列举char是1个字节的情况,我们创建一个长度为256的数组来模拟哈希表,每个字母根据其ASCII码值作为数组的下标对应数组的一个数字,而数组中存储的是每个字符出现的次数。计算下来,它的大小是256*4字节(1个int类型在Windows下占4个字节)=1K。由于这个数组的大小是个常数,因此可以认为这种算法的空间复杂度是O(1)。
三、单元测试
3.1 测试用例
// 常规输入测试,存在只出现一次的字符
[TestMethod]
public void FirstCharTest1()
{
char actual = CharHelper.FirstNotRepeatingChar("google");
Assert.AreEqual(actual, 'l');
} // 常规输入测试,不存在只出现一次的字符
[TestMethod]
public void FirstCharTest2()
{
char actual = CharHelper.FirstNotRepeatingChar("aabccdbd");
Assert.AreEqual(actual, '\0');
} // 常规输入测试,所有字符都只出现一次
[TestMethod]
public void FirstCharTest3()
{
char actual = CharHelper.FirstNotRepeatingChar("abcdefg");
Assert.AreEqual(actual, 'a');
} // 鲁棒性测试,输入NULL
[TestMethod]
public void FirstCharTest4()
{
char actual = CharHelper.FirstNotRepeatingChar(null);
Assert.AreEqual(actual, '\0');
}
3.2 测试结果
(1)测试通过情况

(2)代码覆盖率

四、总结扩展

如果需要判断多个字符是不是在某个字符串里出现过或者统计多个字符在某个字符串中出现的次数,我们都可以考虑基于数组创建一个简单的哈希表(或者使用基类库中提供的现成的哈希表结构类型)。这样可以用很小的空间消耗换来换取时间效率的提升。
剑指Offer面试题:30.第一个只出现一次的字符的更多相关文章
- 剑指Offer - 九度1283 - 第一个只出现一次的字符
剑指Offer - 九度1283 - 第一个只出现一次的字符2013-11-21 21:13 题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出 ...
- 【Java】 剑指offer(50-1) 字符串中第一个只出现一次的字符
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在字符串中找出第一个只出现一次的字符.如输入"abacc ...
- 剑指offer(34)第一个只出现一次的字符
题目描述 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置 题目分析 只需要用map记录字符出现的次数就行,比较简单的题 代码 f ...
- 【剑指Offer】34、第一个只出现一次的字符
题目描述: 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 解题思路: ...
- 剑指offer——面试题30:包含min函数的栈
#include"iostream" #include"stdio.h" using namespace std; ; ; template<typena ...
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 剑指offer面试题30:最小的k个数
一.题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解题思路 1.思路1 首先对数组进行排序,然后取出前k个数 ...
- 剑指offer面试题30.包含min函数的栈
一开始写的垃圾代码,push和pop都是O(N) class Solution { public: vector<int> vec; int min_val=INT_MAX,min_cnt ...
- 剑指offer 面试题56. 数组中只出现一次的两个数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
随机推荐
- 谷歌浏览器对uploadify(swf)上传控件 崩溃问题
页面加上 <script type="text/javascript" src=@Url.Content("~/Content/js/jquery.uploadif ...
- (UWP开发)基于Windows10 Anniversary SDK创造出位于可视化层的DropShadow
Windows.UI.Composition API是可以从任何通用Windows平台应用程序调用的声明性保留模式API,从而可以直接在应用程序中创建合成对象.动画和效果. Composition A ...
- c语言快速入门1
如果你想快速入门计算机,可以参考我的上一篇帖子,先了解一些必备的软知识,然后再来进行语言的快速入门 计算机入门基础知识 目录 1.1.1 计算机与程序 现代计算机可以自动完成计算任务 程序就是按 ...
- iphone 尺寸and字体
iPhone的APP界面一般由四个元素组成,分别是:状态栏.导航栏.主菜单栏以及中间的内容区域 这里取用 640×960 的尺寸设计,那我们就说说在这个尺寸下这些元素的尺寸: 状态栏:就是我们经常说的 ...
- VS自定义项目模板:[2]创建VSIX项目模板扩展
VS自定义项目模板:[2]创建VSIX项目模板扩展 听语音 | 浏览:1237 | 更新:2015-01-02 09:21 | 标签:软件开发 1 2 3 4 5 6 7 分步阅读 一键约师傅 百度师 ...
- ACM: Gym 101047K Training with Phuket's larvae - 思维题
Gym 101047K Training with Phuket's larvae Time Limit:2000MS Memory Limit:65536KB 64bit IO F ...
- POJ 1160 题解
Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18835 Accepted: 10158 Des ...
- git上传代码到osc@git
1.get an account 2.get a ssh-key 3.git setting git config --global user.name "...." git co ...
- Bug管理系统 BugFree
BugFree - 借鉴微软公司软件研发理念.免费且开放源代码.基于Web的精简版Bug管理系统 在线演示:http://www.bugfree.org.cn/demo/Login.php 其它项目管 ...
- Total Commander解压位置
TC解压到当前文件夹下 TC也是用了一段时间,现在勉强也算用习惯了,今天在解压文件的时候感觉步骤麻烦,之前解压都是解压到另一个窗口,所以一直是ALT+8同步窗口,然后解压文件.但一般解压文件都是解压到 ...