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

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

面试学习

一、题目

串联所有单词的子串

二、解题思路

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 函数,返回结果数组。

五、测试代码

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

相关推荐
浮生如梦_1 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
wheeldown4 小时前
【数据结构】选择排序
数据结构·算法·排序算法
观音山保我别报错5 小时前
C语言扫雷小游戏
c语言·开发语言·算法
TangKenny7 小时前
计算网络信号
java·算法·华为
景鹤7 小时前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie7 小时前
SCNU习题 总结与复习
算法
Dola_Pan8 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法