《剑指offer》面试题17:不含重复字符的最长子字符串

"""
题目:输入两个字符串t和s,请找出字符串t中包含字符串s的所有字符的最短字符串。
     例如,输入字符串t为‘ADDBANCAD',字符串s为’ABC',则字符串t中包含字符'A','B'和‘C'的最短字符串为’BANC'
     如果不存在符合条件的字符串,则返回字符串为空字符串。如果存在多个符合条件的子字符串,则返回任意一个
解答思路:该题与第16题的核心考点一样,即如何截取符合条件的最短字符串。即使用双指针从左开始,P2先移动,然后到达某个条件后,P1再移动。
        在此题里,先判断P1-P2是否包含s的所有字符,如果不包含,则P2右移直到P1-P2包含s的所有字符,此时对P1,P2的位置以及P1-P2的长度进行记录
        如果P1-P2包含s的所有字符后,P1右移,直到P1-P2不再包含s的所有字符
        如此循环,直到P1和P2到达字符串t的结尾
"""


def no_repeat(t,s):
    length = len(t)
    t_list = list(t)
    s_set = set(s)
    p1, p2 = 0, 1
    result_dict = {}
    while p1 != length and p2 != length+1:
        sub_t = t_list[p1:p2]
        if s_set.issubset(set(sub_t)):
            sub_length = p2 - p1
            if length not in result_dict:
                result_dict[sub_length] = [(p1, p2)]
            else:
                result_dict[sub_length].append((p1, p2))
            p1 += 1
        else:
            p2 += 1
    if len(result_dict) > 0:

        min_length = min(result_dict.keys())

        p1, p2 = result_dict[min_length][0]
        return t[p1:p2]
    else:
        return ''

s = 'ABC'
t = 'ADDBANCAD'
t2 = 'BANDCSDSS'
t3 = 'BANDSDSSC'
t4 = 'sdsdsdssaassa'
print(no_repeat(t, s))
print(no_repeat(t2, s))
print(no_repeat(t3, s))
print(no_repeat(t4, s))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值