编程题-招式拆解II

某套连招动作记作仅由小写字母组成的序列 arr,其中 arr[i]i 个招式的名字。请返回第一个只出现一次的招式名称,如不存在请返回空格。

解法一(哈希表):

遍历字符串arr,使用哈希表统计“各个字符串数量是否>1”。再遍历字符串arr,在哈希表中找到首个“数量为1的字符”,并返回。笔者实现代码如下所示:

class Solution {
public:
    char dismantlingAction(string arr) {
        //创建哈希表hashTable1以及成员函数返回结果char result = ' ';
        std::unordered_map<char,int> hashTable1;
        char result = ' ';
        //循环遍历for保存哈希表中键值对,其中键为char类型字母,值为在字符串中出现的数量
        for(char c:arr){
            auto it = hashTable1.find(c);
            if(it==hashTable1.end()){
                hashTable1[c]=1;
            }
            else{
                hashTable1[c]++;
            }
        }
        //再次循环遍历arr字符串,找到哈希表中值为1的且第一个出现的char类型字母,并return结果
        for(char c:arr){
            if(hashTable1[c]==1){
                result=c;
                return result;
            }
        }
        return result;
    }
};

时间复杂度 O(N) : N 为字符串 arr 的长度;需遍历 arr 两轮,使用 O(N) ;HashMap 查找操作的复杂度为 O(1) ;空间复杂度 O(1) : 由于题目指出 arr 只包含小写字母,因此最多有 26 个不同字符,HashMap 存储需占用 O(26)=O(1) 的额外空间。

解法二(有序哈希表)

在哈希表的基础上,有序哈希表中的键值对是按照插入顺序排序的。基于此,可通过遍历有序哈希表,实现搜索首个“数量为1的字符”。哈希表是去重的,即哈希表中键值对数量≤字符串arr的长度。因此,相比于方法一,方法二减少了第二轮遍历的循环次数。当字符串很长(重复字符很多)时,方法二则效率更高。由于 C++ 未提供自带的链式哈希表,因此借助一个 vector 按序存储哈希表 hmap 中的 key ,第二轮遍历此 vector 即可。

class Solution {
public:
    char dismantlingAction(string arr) {
        //借助一个容器vector按顺序存储哈希表hmap中的key,第二轮遍历此vector即可。
        vector<char> keys;
        unordered_map<char, bool> hmap;

        for(char c : arr) {
            //如果哈希表hmap未找到字符串c,则将其添加到keys容器中
            if(hmap.find(c) == hmap.end())
                keys.push_back(c);
            //若hamp.find(c) == hmap.end()得到结果true,否则得到结果false
            hmap[c] = hmap.find(c) == hmap.end();
        }
        //遍历此容器中的keys值,顺序读取,当bool为true时在哈希表中仅出现了一次,为flase表示在哈希表中出现一次以上
        for(char c : keys) {
            if(hmap[c]) return c;
        }
        return ' ';
    }
};

笔者小记:

本题考察哈希表的使用,本文介绍“哈希表”和“有序哈希表”两种解法,其中,在字符串长度较大、重复字符很多时,“有序哈希表”解法理论上效率更高。

1、再定义char result 类型字符时,初始化可以将其设置为空,即char result = ‘ ’,而对于string类型的字符串时,初始化可以将其设置为空,即string result = “”。需注意char类型的空字符和string类型的空字符串定义有细微区别,char必须加 ' '空格,而string类型不需要加空格,直接为“”。

2、vector<char> keys定义的容器类型添加元素的顺序是会记录顺序的,即可以通过for(char c : keys)实现对keys中char字符的顺序遍历(添加元素时顺序),而哈希表中添加元素的顺序并不会记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值