C语言 | Leetcode C语言题解之第466题统计重复个数-题解:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <limits.h>

#define MMAX(a, b)        ((a) > (b)? (a) : (b))
#define MMIN(a, b)        ((a) < (b)? (a) : (b))

//【算法思路】字符串。典型的双字符串循环节问题。
// s1:      |abaacdbac | abaacdbac | abaacdbac | abaacdbac | abaacdbac | abaacdbac
// s2:      |a    d  c    b   d|a         d  c    b   d|a     b  c b          d|
// s2_idx:  |0         |3          |1          |3
// s2_cnt:  |0         |0          |1          |1
//--------------------------------------------------------------------------------
// s1_cnt   |0         |1          |2          |3          |4          |5
int getMaxRepetitions(char * s1, int n1, char * s2, int n2){
    if(n1 == 0) {
        return 0;
    }

    int slen1 = strlen(s1);
    int slen2 = strlen(s2);
    //极限情况,最多重复slen2 +1可以遇到重复
    int *s2_idxs = (int *)calloc(slen2 + 1, sizeof(int));
    int *s2_cnts = (int *)calloc(slen2 + 1, sizeof(int));
    int s2_idx = 0;
    int s2_cnt = 0;

    //查找循环节
    for(int i = 0; i < n1; i++) {
        //完成在s1内的一轮查找
        for(int j = 0; j < slen1; j++) {
            if(s1[j] == s2[s2_idx]) {
                s2_cnt = s2_idx == slen2 - 1? s2_cnt + 1 : s2_cnt;
                s2_idx = s2_idx == slen2 - 1? 0 : s2_idx + 1;
            }
        }

        //进行一次记录
        s2_idxs[i] = s2_idx;
        s2_cnts[i] = s2_cnt;

        //在0~i-1的范围内,查找循环节
        for(int j = 0; j < i; j++) {
            if(s2_idxs[j] == s2_idxs[i]) {
                //在循环节之前循环的次数
                //int pre_cnt = s2_cnts[j];
                //循环节中的s2的个数乘以循环次数
                int core_cnt = (s2_cnts[i] - s2_cnts[j]) * ((n1 - 1 - j) / (i - j));
                //将剩余的s1的循环个数加到前面,计算除循环节外的个数
                int pre_and_post_cnt = s2_cnts[j + ((n1 - 1 - j) % (i - j))];

                return (core_cnt + pre_and_post_cnt) / n2;
            }
        }
    }

    return s2_cnts[n1 - 1] / n2;
}
上一篇:F5携手NetApp加速并简化大语言模型AI部署


下一篇:在线表格技术如何助力企业实现全面预算?