多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【剑指offer】66.第一个只出现一次的字符

总目录:

算法之旅导航目录

 

1.问题描述

在一个长为 字符串中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
数据范围:0≤n≤10000,且字符串只有字母组成。
要求:空间复杂度 O(n),时间复杂度 O(n)

 

2.问题分析

 1哈希

看到查找出现次数的就应想到哈希表,因为其时间复杂度O(1)的特性,

需要两次遍历,第1次是填充哈希表,第2次是查询出现次数

2队列+哈希表

题中要求“第一个只出现一次的字符”,意味着该字符前面的字符(如果有的话)是重复的、需要被忽略掉,这种前面的需要被抛弃掉的特性可以想到队列。

对于这些元素,在遍历到输入集合结尾时必然已经遇到,问题是如何将这些元素剔除。

使用一个哈希表来保存元素是否出现过、使用一个队列来保证元素出现的顺序。

遍历元素时如果是新元素,则将其加入到哈希表中、并在队列中入队;

如果是已经遇到过的元素,则触发对队列中front元素的重复性检查、如果重复则出队、while循环此操作直到front元素尚未重复。

这样使用循环嵌套使得表面上看起来只对输入集合遍历了一次。,当遍历完成后,front元素即只出现了一次的元素,问题是它的地址是多少?

只需要队列中储存的是pair<val,addr>即可。


3.代码实例

哈希

复制代码
 1 class Solution {
 2   public:
 3     int FirstNotRepeatingChar(string str) {
 4         unordered_map<char, int> maps;
 5         for (char a : str) {
 6             maps[a]++;
 7         }
 8 
 9         for (int i = 0; i < str.length(); i++) {
10             if (maps[str[i]] == 1) {
11                 return i;
12             }
13         }
14 
15         return -1;
16     }
17 };
复制代码

 队列+哈希

复制代码
 1 class Solution {
 2 public:
 3     int FirstNotRepeatingChar(string str) {
 4         //统计字符出现的位置
 5         unordered_map<char, int> mp; 
 6         queue<pair<char, int> > q; 
 7         for(int i = 0; i < str.length(); i++){
 8             //没有出现过的字符
 9             if(!mp.count(str[i])){ 
10                 mp[str[i]] = i; 
11                 q.push(make_pair(str[i], i));
12             //找到重复的字符
13             }else{ 
14                 //位置置为-1
15                 mp[str[i]] = -1; 
16                 //弹出前面所有的重复过的字符
17                 while(!q.empty() && mp[q.front().first] == -1) 
18                     q.pop();
19             }
20         }
21         return q.empty() ? -1 : q.front().second;
22     } 
23 };
复制代码

需要注意的是:

第二种方法速度有提升但也不能说只需要遍历一次,只是因为循环的嵌套使得最外层的循环看起来只遍历了1次。 在时间复杂度上最坏的情况是唯一出现一次的值在正中间、且输入序列中第0个和最后一个重合,这就使得在遍历到最后一个元素时需要出队n/2次才能找到目标值。 方法1时间复杂度是O(2n),方法2时间复杂度是O(n+n/2)

本文作者:啊原来是这样呀

本文链接:https://www.cnblogs.com/OhOfCourse/p/16953200.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起