当前位置: 首页 > article >正文

算法练习:438. 找到字符串中所有字母异位词

题目链接:438. 找到字符串中所有字母异位词

我们来分析这个题目,题目意思就是,在s字符串中寻找包含p的异位次的字串,字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次。

那我们来看看如何解出这题

暴力解法:把p放入哈希表中,依次枚举s字串进行比较,时间复杂度是O(N平方),这种解法会超时。

在暴力解法的前提下进行对其优化:

优化:不用依次枚举,当哈希表个数超了,只需要删除第一个数,不需要从头再开始遍历

同向进行移动,就可以利用滑动窗口思想:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        map<char, int> m1;
        map<char, int> m2;
        vector<int> n;
        int sum1 = 0;
        int sum2 = 0;
        for (int i = 0; i < p.size(); i++)
        {
            m1[p[i]]++;
            sum1++;
        }
        for (int left=0, right = 0; right < s.size(); right++)
        {
            m2[s[right]]++;
            sum2++;
            if (sum1 == sum2)
            {
                auto it1 = m1.begin();
                auto it2 = m2.begin();
                while (it1 != m1.end() && it2 != m2.end())
                {
                    if ((it1->first != it2->first)|| (it1->second != it2->second))
                    break;
                    it1++;
                    it2++;
                }
                if (it1 == m1.end()) n.push_back(left);
                left++;
                sum2--;
                m2[s[left - 1]]--;
                if(m2[s[left - 1]]==0)
                m2.erase(s[left - 1]);
            }

        }
        return n;
    }
};

还可以进行优化,可以用数组来模拟哈希表,减少了消耗:

class Solution {
public:
    bool check(int *h1,int *h2)
    {
        int i = 0;
        while(i<26)
        {
            if(*(h1 + i) != *(h2 + i)) return false;
            i++;
        }
        return true;
    }
    
    vector<int> findAnagrams(string s, string p) {
        int h1[26] = {0};
        for(auto e: p) h1[e-'a']++;
        int h2[26] = {0};
        vector<int> n;
        for(int left = 0,right = 0;right < s.size();right++)
        {
            h2[s[right]-'a']++;
            if(right-left+1 > p.size())
            {
                h2[s[left]-'a']--;
                left++;
            }
            if(check(h1,h2))
            {
                n.push_back(left);
            }
        }
        return n;
    }
};

我们还可以对更新条件进行优化,定义一个变量count,来记录有效个数

这样我们就可以一边进行插入,移除,一边维护count,从而可以确定什么时候来更新 

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int h1[26] = {0};
        for(auto e: p) h1[e-'a']++;
        int h2[26] = {0};
        vector<int> n;
        for(int left = 0,right = 0,count = 0;right < s.size();right++)
        {
            //h2[s[right]-'a']++;
            if(++h2[s[right]-'a'] <= h1[s[right]-'a']) count++;
            if(right-left+1 > p.size())
            {
                if(h2[s[left]-'a']-- <= h1[s[left]-'a']) count--;
                //h2[s[left]-'a']--;
                left++;
            }
            if(count == p.size())
            {
                n.push_back(left);
            }
        }
        return n;
    }
};


http://www.kler.cn/a/397639.html

相关文章:

  • Amazon Web Services (AWS)
  • 【CV】头盔检测区域入侵项目
  • 接上篇-使用 element-plus 优化UI界面
  • 【数据库系列】 Spring Boot 集成 Neo4j 的详细介绍
  • 基于OpenCV的图片人脸检测研究
  • MongoDB分布式集群搭建----副本集----PSS/PSA
  • 【Rust中的项目管理】
  • vue之axios根据某个接口创建实例,并设置headers和超时时间,捕捉异常
  • MySQL8 安装教程
  • 【网络安全面经】技术性问题
  • 大数据治理:构建高效数据生态的基石
  • 前端:HTML/CSS/JavaScript基础知识
  • 深入理解 source 和 sh、bash 的区别
  • 【jvm】分代年龄为什么是15次
  • C语言之链表操作
  • C语言第九周课——经典算法
  • 从系统崩溃到绝地反击:一次微服务存储危机的救赎
  • 在uniapp当中隐藏掉默认tabbar并且使用自己的tabbar
  • 查看解决端口占用,以及docker解决端口占用的原理
  • char* 指针转换与打印
  • 【MySQL】MySQL中的函数之JSON_REPLACE
  • Jmeter中的监听器(四)
  • 电动机三角型与星型的区别和接线方法图解
  • 新手小白学习docker第七弹------安装redis集群大厂面试
  • 从H3C和Dell官网下载OEM版VMware Esxi镜像攻略
  • 大数据技术之HBase中的HRegion