30. 串联所有单词的子串【memset(hash, 0, sizeof(hash)) 这样的方式真的不要再使用、leetcode有时真的会g的】

这篇具有很好参考价值的文章主要介绍了30. 串联所有单词的子串【memset(hash, 0, sizeof(hash)) 这样的方式真的不要再使用、leetcode有时真的会g的】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

30. 串联所有单词的子串

30. 串联所有单词的子串【memset(hash, 0, sizeof(hash)) 这样的方式真的不要再使用、leetcode有时真的会g的】


C代码:滑动窗口、字符串异位段

// 此题是 字母异位词 的进阶题;字符串异位段
// 1、创建words的哈希表,记录word、次数、下标idx(对比438,相当于是判断哈希数组相等!)
// 2、类比判断哈希数组相等的条件:遍历每一个str,str出现在words中,次数相等,窗口的长度与words所有串的长度相等!
// 3、str不出现在words中,l右移一个step,清空hash,重新开始;
// 4、hash[idx] > cnt 滑动窗口左移;

typedef struct {
    char *str;
    int cnt;
    int idx;
    UT_hash_handle hh;
} HashTable;

HashTable* AddHash(char **words, int wordsSize) {
    HashTable* head = NULL;
    HashTable* out = NULL;
    for (int r = 0; r < wordsSize; r++) {
        HASH_FIND_STR(head, words[r], out);
        if(NULL == out) {
            out = (HashTable*)malloc(sizeof(HashTable));
            out->str = words[r];
            out->cnt = 1;
            out->idx = r;
            HASH_ADD_STR(head, str, out);
        } else {
            out->cnt++;
        }
    }
    return head;
}

int* findSubstring(char * s, char** words, int wordsSize, int* returnSize){
    int step  = strlen(words[0]);  // words的字符串长度相等
    int lenHash = step * wordsSize;
    int lenS = strlen(s);
    
    int* arr = (int *)malloc(sizeof(int) * lenS);
    int* hash  = (int*)malloc(sizeof(int) * wordsSize);
    
    int k = 0;
    HashTable* head = AddHash(words, wordsSize);  // 构造哈希
    HashTable* out = NULL;
    for (int i = 0; i < step; ++i) {  // 窗口左侧步进是一个step,所以要遍历一个step里面的左右起点
        int l = i;
        memset(hash, 0, sizeof(int) * wordsSize);
        
        for (int r = i; r < lenS; r += step) {  // 窗口右侧一个步进、一个步进前进
            char str[step + 1];
            str[0] = '\0';
            strncat(str, s + r, step);  // 截取一个step的字符串、查找
            HASH_FIND_STR(head, str, out);
            if(NULL == out) {   // 未找到,就得重新归零、重新开始,移至下一个元素开头
                memset(hash, 0, sizeof(int) * wordsSize);  // 用hash数组代替uthash的增删; 
                l = r + step;                              // hash数组:滑动窗口中个字符串出现的次数!
            } else {  // 窗口中的截取串str在words中出现了,窗口内左侧的子串一定是出现在words里面的!
                int idx = out->idx;
                int cnt = out->cnt;
                hash[idx]++;         // 统计str出现的次数,hash为words的字符串各自出现在窗口中的次数;
                while(hash[idx] > cnt) {    // 在满足条件的结果中:一个word的次数少了,必定导致另外一个word的次数多了
                    char str1[step + 1]; 
                    str1[0] = '\0';
                    strncat(str1, s + l, step);
                    HASH_FIND_STR(head, str1, out);
                    hash[out->idx]--;
                    l += step;
                }

                if (r - l + step == lenHash) {  // 窗口匹配后、窗口左侧右移一个step,并hash[idx]--;
                    arr[k++] = l;               // 记录ans结果
                    char str1[step + 1];
                    str1[0] = '\0';
                    strncat(str1, s + l, step);
                    HASH_FIND_STR(head, str1, out);
                    hash[out->idx]--;
                    l += step;
                }
            }
        }
    }
    *returnSize = k;
    return arr;
}

C代码:失败案例:哈希表保存重复出现文章来源地址https://www.toymoban.com/news/detail-433452.html

typedef struct {
    char *str;
    int cnt;
    int idx;
    UT_hash_handle hh;
} HashTable;

HashTable* AddHash(char **words, int wordsSize) {
    HashTable* head = NULL;
    HashTable* out = NULL;
    for (int r = 0; r < wordsSize; r++) {
        HASH_FIND_STR(head, words[r], out);
        if(NULL == out) {
            out = (HashTable*)malloc(sizeof(HashTable));
            out->str = words[r];
            out->cnt = 1;
            out->idx = r;
            HASH_ADD_STR(head, str, out);
        } else {
            out->cnt++;
        }
    }
    return head;
}

int* findSubstring(char * s, char** words, int wordsSize, int* returnSize){
    int step  = strlen(words[0]);
    int lenHash = step * wordsSize;
    int lenS = strlen(s);
    
    int* arr = (int *)malloc(sizeof(int) * lenS);
    int* hash  = (int*)malloc(sizeof(int) * wordsSize);
    
    int k = 0;
    HashTable* head = AddHash(words, wordsSize);
    HashTable* out = NULL;
    for (int i = 0; i < step; ++i) {  // 遍历初始节点
        int l = i;
        memset(hash, 0, sizeof(int) * wordsSize);
        
        for (int r = i; r < lenS; r += step) {  // 从初始节点开始,一段一段遍历
            char str[step + 1];
            strncpy(str, s + r, step);
            HASH_FIND_STR(head, str, out);
            if(NULL == out) {   // 未找到,就得重新归零、重新开始,移至下一个元素开头
                memset(hash, 0, sizeof(int) * wordsSize);  // 用hash数组代替uthash的增删; 
                l = r + step;                              // hash数组:滑动窗口中个字符串出现的次数!
            } else {
                int idx = out->idx;
                int cnt = out->cnt;
                hash[idx]++;         // 下标出现过、hash[idx]次数
                while(hash[idx] > cnt) {  // 经典的滑动窗口套路,滑动窗口中个字符串出现的次数 > uthash中该字符串出现的次数
                    char str1[step + 1];                    // 窗口就应该收缩左边!直到窗口中字符串次数满足uthash的
                    strncpy(str1, s + l, step);
                    HASH_FIND_STR(head, str1, out);
                    hash[out->idx]--;
                    l += step;
                }

                if (r + step - l == lenHash) {  // 窗口匹配后、l右移1个step,并hash[idx]--;
                    arr[k++] = l;         // 记录结果,l并左移一个step;
                    char str1[step + 1];
                    strncpy(str1, s + l, step);
                    HASH_FIND_STR(head, str1, out);
                    hash[out->idx]--;
                    l += step;
                }
            }
        }
    }
    *returnSize = k;
    return arr;
}


到了这里,关于30. 串联所有单词的子串【memset(hash, 0, sizeof(hash)) 这样的方式真的不要再使用、leetcode有时真的会g的】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 每日OJ题_算法_滑动窗口⑦_力扣30. 串联所有单词的子串

    目录 力扣30. 串联所有单词的子串 解析及代码 30. 串联所有单词的子串 - 力扣(LeetCode) 难度 困难 给定一个字符串  s   和一个字符串数组  words 。   words  中所有字符串  长度相同 。   s   中的  串联子串  是指一个包含   words  中所有字符串以任意顺序排列连接起来的

    2024年01月21日
    浏览(34)
  • 【算法】串联所有单词的子串【滑动窗口】

    滑动窗口

    2024年01月19日
    浏览(33)
  • 【Java刷题篇】串联所有单词的子串

    力扣链接: 串联所有单词的子串 阅读题目后,可以拿到一个关键信息– words中所有字符串长度相等 ,这后续解题思路的一大关键,还有就是串联字串的字符串顺序可以不同。得到这两个关键信息后,我们就很容易联想到运用 滑动窗口 这个算法来解决问题。 好分析完题目后,

    2024年03月22日
    浏览(34)
  • c 取字符串中的子串

    strcpy(S.ch,ch1) 赋值函数; 字符串没特殊处理,就是从0开始的 %s输出字符串,%c输出字符

    2024年02月07日
    浏览(28)
  • 【LeetCode热题100】【子串】和为 K 的子数组

    题目 给你一个整数数组  nums  和一个整数  k  ,请你统计并返回  该数组中和为  k   的子数组的个数  。 子数组是数组中元素的连续非空序列。 示例 1: 示例 2: 提示: 1 = nums.length = 2 * 104 -1000 = nums[i] = 1000 -107 = k = 107 暴力  直接两层循环找出所有连续子数组的和,这个

    2024年01月19日
    浏览(26)
  • C++string类replace()函数(替换字符串中的子串)

    C++中的string类提供了replace()函数,用于替换字符串中的子串。其函数原型如下: 其中,pos表示要替换的子串在原字符串中的起始位置,len表示要替换的子串的长度,str表示用来替换的字符串。 replace()函数的使用方法非常简单,只需要传入要替换的子串的位置、长度和替换字

    2024年02月05日
    浏览(40)
  • OJ练习第84题——按字典序排在最后的子串

    力扣链接:1163. 按字典序排在最后的子串 给你一个字符串 s ,找出它的所有子串并按字典序排列,返回排在最后的那个子串。 示例 1: 输入:s = “abab” 输出:“bab” 解释:我们可以找出 7 个子串 [“a”, “ab”, “aba”, “abab”, “b”, “ba”, “bab”]。按字典序排在最后的

    2023年04月24日
    浏览(26)
  • 【新2023Q2模拟题JAVA】华为OD机试 - 符合条件的子串长度

    华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单 华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典 【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南 华为od机试,独家整理 已参加机试人员的实战技巧 给定字符串 A 、 B 和正整数 V , 字符串 A 和 B 的长度相

    2023年04月18日
    浏览(31)
  • 【算法|动态规划No30】leetcode5. 最长回文子串

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助 🍓希望我们一起努力、成长,共同进步。

    2024年02月08日
    浏览(29)
  • 【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

    1. 长度最小的子数组 - 力扣(LeetCode) (1)方法一:暴力列举出所有的子数组的和 时间复杂度:O(n**2):枚举所有子数组O(n**2) (2)方法二: 利用 单调性(两个指针都不回退) ,使用\\\" 同向双指针 \\\"(其实就是 滑动窗口 )来优化 那么 滑动窗口过程 是怎么样的? 1le

    2024年03月22日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包