📌  相关文章
📜  教资会网络 | UGC NET CS 2017 年一月至三日 |问题 55(1)

📅  最后修改于: 2023-12-03 14:54:50.751000             🧑  作者: Mango

教资会网络 | UGC NET CS 2017 年一月至三日 |问题 55

简介

教资会网络(UGC NET)是印度全国大学委员会(National Testing Agency, NTA)主办的一个全国性考试,考察的是计算机科学与应用领域的基础知识、理解和应用能力。2017 年一月至三日的 UGC NET 考试中,共有 6 道编程题目,其中第 55 题是本题。

问题描述

给定一个字符串 s 和一个正整数 k,找到字符串 s 中最长的连续子串,其包含不超过 k 个不同的字符,返回该子串的长度。

输入格式
  • 第一行输入一个字符串 s(1≤s≤10^5),字符串中只包含小写字母。
  • 第二行输入一个正整数 k(1≤k≤26)。
输出格式

输出一个正整数表示最长的连续子串的长度。

样例

输入样例:

eceba
2

输出样例:

3
解题思路

这是一个经典的滑动窗口题目,可以使用左右指针维护一个滑动窗口。首先让右指针移动,当窗口中的不同字符数大于 k 时,让左指针移动并更新窗口中的字符出现次数,直到窗口中不同字符数小于等于 k。

代码实现
def longestSubstring(s: str, k: int) -> int:
    n = len(s)
    if k > len(set(s)):
        return 0

    l, r, counter, res = 0, 0, 0, 0
    freq = [0] * 26

    while r < n:
        freq[ord(s[r]) - ord('a')] += 1
        if freq[ord(s[r]) - ord('a')] == 1:
            counter += 1
        r += 1

        while counter > k:
            freq[ord(s[l]) - ord('a')] -= 1
            if freq[ord(s[l]) - ord('a')] == 0:
                counter -= 1
            l += 1

        res = max(res, r - l)

    return res

该函数接收两个参数,一个字符串 s 和一个正整数 k。首先判断 k 是否大于字符串 s 中不同字符的数量,如果大于,则返回 0。然后定义左右指针 l 和 r,一个计数器 counter,和一个长度变量 res,最后初始化一个长度为 26 的数组 freq,用来记录窗口中每个字符出现的次数。

接着进入主循环,右指针 r 不断向右移动,将窗口中新的字符加入 freq 数组,并判断这个字符是否是窗口中第一次出现,如果是,则计数器 counter 加 1。当窗口中不同的字符数量大于 k 时,左指针 l 开始向右移动,并更新 freq 数组。如果 freq 数组中某个字符的出现次数减到 0,说明该字符已经不在当前窗口中,此时计数器 counter 减 1。在左指针移动的过程中,不断更新长度变量 res 的值,最终返回 res 即可。