前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试之算法基础系列1.最多有k个不同字符的最长子字符串

面试之算法基础系列1.最多有k个不同字符的最长子字符串

作者头像
cutercorley
发布2021-01-05 09:54:16
5680
发布2021-01-05 09:54:16
举报
文章被收录于专栏:Corley的开发笔记

文章目录

1.最长子字符串

题目原为:

【题目】 给定一个字符串,给定一个数字k ( 0< k ≤ 字符串长度),输出最长的包含k个不同字符子串的长度。 【Example】 “cbca”, k=2,输出最长的包含2个不同字符子串的长度。 答案:3 题目来源:百度 SRE工程师实习生 一面,可点击https://www.nowcoder.com/discuss/585284查看一面凉经/(ㄒoㄒ)/~~

最容易想到的是暴力解法,就是遍历求出字符串的所有子串,并找出不同字符为k的最长字符,Python代码如下:

代码语言:javascript
复制
def find_max_substring(string, k):
    str_length = len(string)
    sub_string_list = (string[i:i + j + 1] for j in range(str_length) for i in range(str_length - j))
    length_list = []
    for sub_string in sub_string_list:
        if len(set(list(sub_string))) == k:
            length_list.append(len(sub_string))
    return max(length_list)
 
 
if __name__ == '__main__':
    string = input()
    k = int(input())
    max_length = find_max_substring(string, k)
    print(max_length)

显然,这种实现方式效率是很低的,虽然使用了生成器,但是在性能方面还是有很大的问题,同时未考虑特殊情况。 后来查询了一些资料,使用了同向双指针和字典来对实现方式进行了优化:

代码语言:javascript
复制
def find_max_substring(string, k):
    str_length = len(string)
    if str_length == 0 or k == 0:
        return 0
    count = 0
    left = 0
    right = 0
    res = 0
    count_dic = {}
    while right < str_length:
        if string[right] not in count_dic or count_dic[string[right]] == 0:
            count += 1
            count_dic[string[right]] = 1
        else:
            count_dic[string[right]] += 1
        right += 1
        while count > k:
            count_dic[string[left]] -= 1
            if count_dic[string[left]] == 0:
                count -= 1
            left += 1
        res = max(res, right - left)
    return res


if __name__ == '__main__':
    string = input()
    k = int(input())
    max_length = find_max_substring(string, k)
    print(max_length)

在字符串长度为0或者k为0时直接返回0; 通过使用同向双指针的方式,可以做到只遍历一次字符串就能得到答案,从而使时间复杂度为O(n),在字符串上移动滑动窗口的两个指针,来保证窗口内的字符不超过k个,具体如下:

  • 设置指针left、right初始位置均为0,初始化计数数组;
  • 当right小于字符串长度时,每次判断字符s[right]是否位于计数数组中,不在则计数count加1,同时对字典进行更新,并使right指针向右移动;
    • 在字符数超过k时,需要移去窗口中最左侧的字符string[left],同时向右移动left指针使得滑动窗口只包含k个不同字符;
    • 更新最大长度res = max(res, right - left)

此时运行结果如下:

可以看到,运行效率还是相对较快的。 可以在https://www.lintcode.com/problem/longest-substring-with-at-most-k-distinct-characters/description使用IDE进行运行测试和性能评估。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1.最长子字符串
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档