(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)

题目:30. 串联所有单词的子串



思路:哈希表+字符串+滑动窗口,时间复杂度0(mlen)。
因为每个字符串的长度都相等,在维护窗口i~i+m
len的元素出现情况后,可以从i+len处继续往后移动。细节看注释。

C++版本:

cpp 复制代码
class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
    	// 答案
        vector<int> v;
        int n=s.size();
        int m=words.size();
        int len=words[0].size();
        if(n<m*len) return v;
		// 从0~len-1开始遍历
        for(int i=0;i<len&&i+m*len<=n;i++){
        	// 哈希表
            unordered_map<string,int> mp;
            //把words的元素都+1
            for(auto x:words){
                mp[x]++;
            }
            // 先维护窗口i~i+m*len的元素出现情况
            for(int j=0;j<m;j++){
                string t=s.substr(i+j*len,len);
                mp[t]--;
                if(mp[t]==0){
                    mp.erase(t);
                }
            }
            // 如果哈希表为空,说明刚好匹配
            if(mp.size()==0) v.push_back(i);
            // 因为每个字符串的长度都相等,所以可以从i+len处继续往后移动
            for(int j=i+len;j+m*len<=n;j+=len){
            	// 加入新的字符串
                string t=s.substr(j+(m-1)*len,len);
                mp[t]--;
                if(mp[t]==0) mp.erase(t);
                // 删掉旧的字符串
                t=s.substr(j-len,len);
                mp[t]++;
                if(mp[t]==0) mp.erase(t);
                // 如果哈希表为空,说明刚好匹配
                if(mp.size()==0) v.push_back(j);
            }
        }
        return v;
    }
};

JAVA版本:

java 复制代码
class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> v=new ArrayList<>();
        int n=s.length();
        int m=words.length;
        int len=words[0].length();
        if(n<m*len) return v;

        for(int i=0;i<len&&i+m*len<=n;i++){
            Map<String,Integer> mp=new HashMap<>();
            for(var x:words){
                mp.merge(x,1,Integer::sum);
            }
            for(int j=0;j<m;j++){
                String t=s.substring(i+j*len,i+(j+1)*len);
                mp.merge(t,-1,Integer::sum);
                if(mp.get(t)==0){
                    mp.remove(t);
                }
            }
            if(mp.isEmpty()) v.add(i);
            for(int j=i+len;j+m*len<=n;j+=len){
                String t=s.substring(j+(m-1)*len,j+m*len);
                mp.merge(t,-1,Integer::sum);
                if(mp.get(t)==0) mp.remove(t);
                t=s.substring(j-len,j);
                mp.merge(t,1,Integer::sum);
                if(mp.get(t)==0) mp.remove(t);
                if(mp.isEmpty()) v.add(j);
            }
        }
        return v;
    }
}

GO版本:

go 复制代码
func findSubstring(s string, words []string) []int {
    v:=[]int{}
    n,m:=len(s),len(words)
    lens:=len(words[0])
    if n<m*lens {
        return v
    }
    for i:=0;i<lens&&i+m*lens<=n;i++ {
        mp := make(map[string]int)
        for j:=0;j<m;j++ {
            mp[words[j]]++
        }
        for j:=0;j<m;j++ {
            t:=s[i+j*lens:i+(j+1)*lens]
            mp[t]--
            if mp[t]==0 {
                delete(mp,t)
            }
        }
        if len(mp) == 0 {
            v = append(v, i)
        }
        for j:=i+lens;j+m*lens<=n;j+=lens {
            t:=s[j-lens:j]
            mp[t]++
            if mp[t]==0 {
                delete(mp,t)
            }
            t=s[j+(m-1)*lens:j+m*lens]
            mp[t]--
            if mp[t] ==0 {
                delete(mp,t)
            }
            if len(mp) == 0 {
                v = append(v, j) 
            }

        }
    }
    return v
}
相关推荐
一 乐2 分钟前
医院排班|医护人员排班系统|基于springboot医护人员排班系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·医护人员排班系统
一只咸鱼大王36 分钟前
C++ constexpr:编译时计算的高效秘籍
开发语言·c++
绝无仅有38 分钟前
Go 错误处理:用 panic 取代 err != nil 的模式
后端·面试·github
君万1 小时前
【LeetCode每日一题】21. 合并两个有序链表 2. 两数相加
算法·leetcode·链表
绝无仅有1 小时前
Go 面试指南:协程与线程的区别与联系
后端·面试·架构
稚辉君.MCA_P8_Java1 小时前
HTTP的状态码有哪些,并用例子说明一下
java·服务器·jvm·http·kubernetes
神里流~霜灭1 小时前
Fourier 级数展开(案例:级数展开 AND 求和)
c语言·c++·算法·matlab·fourier 级数展开·级数展开求和·fourier算法
the beard1 小时前
Java类加载与JVM详解:从基础到双亲委托机制
java·jvm
纪东东2 小时前
做一个实用的节假日工具
java·开发语言
毕设源码余学姐2 小时前
计算机毕设javayit商城 基于SSM框架的校园二手交易全流程管理系统设计与实现 Java+MySQL的校园二手商品交易与供需对接平台开发
java·mysql·课程设计