【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引

串联所有单词的子串,找到所有符合条件的串联子串的起始索引

面试学习

一、题目

串联所有单词的子串

二、解题思路

2.1 定义子串长度

所有字符串 words 的长度是相同的,假设为 L。那么一个有效的串联子串的总长度应该是 L * len(words)。

2.2 滑动窗口

我们可以使用滑动窗口的方法来遍历字符串 s。窗口的大小应为 L * len(words)。在每个窗口内,我们检查是否可以找到 words 中所有字符串的一个排列。

2.3 哈希表

我们可以使用哈希表来记录 words 中每个字符串出现的次数,并使用另一个哈希表来记录当前窗口中每个字符串的出现次数。

2.4 验证子串

对于每个窗口,检查窗口中字符串的出现次数是否与 words 中字符串的出现次数一致。如果一致,则记录窗口的起始索引。


三、代码实现

复制代码
// Helper function to check if two hash tables are equal
int areHashTablesEqual(int *hash1, int *hash2, int size) {
    for (int i = 0; i < size; i++) {
        if (hash1[i] != hash2[i]) {
            return 0;
        }
    }
    return 1;
}

void findSubstring(char *s, char **words, int wordsSize, int wordLen, int *result, int *returnSize) {
    int sLen = strlen(s);
    int concatLen = wordsSize * wordLen;
    int *wordCount = (int *)calloc(256, sizeof(int));
    int *windowCount = (int *)calloc(256, sizeof(int));

    // Initialize wordCount hash table
    for (int i = 0; i < wordsSize; i++) {
        for (int j = 0; j < wordLen; j++) {
            wordCount[(unsigned char)words[i][j]]++;
        }
    }

    for (int i = 0; i <= sLen - concatLen; i++) {
        memset(windowCount, 0, 256 * sizeof(int));
        int j;
        for (j = 0; j < wordsSize; j++) {
            char *word = s + i + j * wordLen;
            for (int k = 0; k < wordLen; k++) {
                windowCount[(unsigned char)word[k]]++;
            }
        }
        if (areHashTablesEqual(wordCount, windowCount, 256)) {
            result[(*returnSize)++] = i;
        }
    }

    free(wordCount);
    free(windowCount);
}

int* findSubstringIndices(char *s, char **words, int wordsSize, int *returnSize) {
    int wordLen = strlen(words[0]);
    int *result = (int *)malloc(sizeof(int) * 1000); // Allocate enough space for result
    *returnSize = 0;

    findSubstring(s, words, wordsSize, wordLen, result, returnSize);
    return result;
}

四、代码讲解

4.1 areHashTablesEqual

检查两个哈希表是否相等。

4.2 findSubstring

主要逻辑,包括:

  • 初始化哈希表 wordCount 记录 words 中所有字符串的出现次数。
  • 使用滑动窗口方法检查每个窗口内的字符出现次数是否匹配 wordCount。
  • 如果匹配,将窗口的起始索引存入结果数组。

4.3 findSubstringIndices

封装 findSubstring 函数,返回结果数组。

五、测试代码

串联所有单词的子串,找到所有符合条件的串联子串的起始索引

相关推荐
得物技术6 分钟前
RAG—Chunking策略实战|得物技术
数据库·人工智能·算法
gugugu.1 小时前
算法:滑动窗口类型题目的总结
算法·哈希算法
大数据张老师2 小时前
数据结构——直接插入排序
数据结构·算法·排序算法·1024程序员节
hoiii1872 小时前
基于SVM与HOG特征的交通标志检测与识别
算法·机器学习·支持向量机
进击的炸酱面2 小时前
第四章 决策树
算法·决策树·机器学习
爱coding的橙子2 小时前
每日算法刷题Day81:10.29:leetcode 回溯5道题,用时2h
算法·leetcode·职场和发展
大千AI助手3 小时前
Householder变换:线性代数中的镜像反射器
人工智能·线性代数·算法·决策树·机器学习·qr分解·householder算法
Mr.H01273 小时前
迪杰斯特拉(dijkstra)算法
算法
南方的狮子先生3 小时前
【数据结构】从线性表到排序算法详解
开发语言·数据结构·c++·算法·排序算法·1024程序员节
派大星爱吃猫3 小时前
快速排序和交换排序详解(含三路划分)
算法·排序算法·快速排序·三路划分