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

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

面试学习

一、题目

串联所有单词的子串

二、解题思路

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

五、测试代码

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

相关推荐
AI 嗯啦3 分钟前
计算机的排序方法
数据结构·算法·排序算法
l12345sy16 分钟前
Day23_【机器学习—聚类算法—K-Means聚类 及评估指标SSE、SC、CH】
算法·机器学习·kmeans·聚类·sse·sc·ch
_Coin_-29 分钟前
算法训练营DAY58 第十一章:图论part08
数据结构·算法·图论
scx201310041 小时前
P13929 [蓝桥杯 2022 省 Java B] 山 题解
c++·算法·蓝桥杯·洛谷
YC运维1 小时前
Ansible题目全解析与答案
java·算法·ansible
小欣加油2 小时前
leetcode 912 排序数组(归并排序)
数据结构·c++·算法·leetcode·排序算法
山河君3 小时前
webrtc之高通滤波——HighPassFilter源码及原理分析
算法·音视频·webrtc·信号处理
星辰大海的精灵3 小时前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
data myth3 小时前
力扣1210. 穿过迷宫的最少移动次数 详解
算法·leetcode·职场和发展
惯导马工3 小时前
【论文导读】AI-Assisted Fatigue and Stamina Control for Performance Sports on IMU-Gene
深度学习·算法