424. 替换后的最长重复字符【数组哈希、uthash-HASH_SORT(head, cmp)】

424. 替换后的最长重复字符

在这里插入图片描述


C代码1:滑动窗口

// 滑动窗口中最多允许存在 k + 1个元素;----解读错误,反例:AAAABC
// 应为:len-maxCnt==k
// "最多" 更改k次,例如k==2,可以更改 0,1,2 次

int GetMax(int *arr) {
    int max = 0;
    for (int i = 0; i < 26; i++) {
        max = fmax(max, arr[i]);
    }
    return max;
}

int characterReplacement(char * s, int k){
    int l = 0;
    int r = 0;
    int len = strlen(s);
    int maxLen = 0;
    int arr[26] = {0};
    for (; r < len; ++r) {
        arr[s[r] - 'A']++;
        int maxNum = GetMax(arr);  // 因为窗口中存在其他的字母,选择最长的为基准,然后以长度为核心移动窗口
        while (r - l + 1 - maxNum > k) {
            arr[s[l] - 'A']--;
            ++l;
            maxNum = GetMax(arr);
        }
        maxLen = fmax(maxLen, r - l + 1);  // 最多更替k次,即 r-l+1-maxCnt <= k 才符合题意
    }
    return maxLen;
}

C代码2:哈希表

使用 HASH_SORT(head, cmp);

typedef struct {
    char ch;
    int cnt;
    UT_hash_handle hh;
} HashEntry;

int cmp (const void* a, const void* b) {
    HashEntry* x = (HashEntry*)a;
    HashEntry* y = (HashEntry*)b;
    return y->cnt - x->cnt;
}

int characterReplacement(char * s, int k){
    int l = 0;
    int r = 0;
    int len = strlen(s);
    int maxLen = 0;
    HashEntry* head = NULL;
    HashEntry* out = NULL;
    for (; r < len; ++r) {
        HASH_FIND(hh, head, &s[r], sizeof(char), out);
        if (out == NULL) {
            out = (HashEntry*)malloc(sizeof(HashEntry));
            out->ch = s[r];
            out->cnt = 1;
            HASH_ADD(hh, head, ch, sizeof(char), out);
        } else {
            out->cnt++;
        }

        HASH_SORT(head, cmp);
        while (r - l + 1 - head->cnt > k) {
            HASH_FIND(hh, head, &s[l], sizeof(char), out);
            out->cnt--;
            ++l;
            HASH_SORT(head, cmp);
        }
        maxLen = fmax(maxLen, r - l + 1);
    }
    return maxLen;
}

不使用 HASH_SORT(head, cmp);

typedef struct {
    char ch;
    int cnt;
    UT_hash_handle hh;
} HashEntry;

int GetMax(HashEntry *head) {
    HashEntry* cur = NULL;
    HashEntry* next = NULL;
    int max = 0;
    HASH_ITER(hh, head, cur, next) {
        max = fmax(max, cur->cnt);
    }
    return max;
}

int characterReplacement(char * s, int k){
    int l = 0;
    int r = 0;
    int len = strlen(s);
    int maxLen = 0;
    HashEntry* head = NULL;
    HashEntry* out = NULL;
    int maxNum = 0;
    for (; r < len; ++r) {
        HASH_FIND(hh, head, &s[r], sizeof(char), out);
        if (out == NULL) {
            out = (HashEntry*)malloc(sizeof(HashEntry));
            out->ch = s[r];
            out->cnt = 1;
            HASH_ADD(hh, head, ch, sizeof(char), out);
        } else {
            out->cnt++;
        }

        maxNum = GetMax(head);
        while (r - l + 1 - maxNum > k) {
            HASH_FIND(hh, head, &s[l], sizeof(char), out);
            out->cnt--;
            ++l;
            maxNum = GetMax(head);
        }
        maxLen = fmax(maxLen, r - l + 1);
    }
    return maxLen;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值