leetcode3题 题解 翻译 C语言版 Python版

3. Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring"pwke" is a subsequence and not a substring.

3. 无重复字符的最长子串

给定一个字符串,找出其无重复字符的最长子串

例如:

给定"abcabcbb", 结果是 "abc", 它的长度是3.

给定"bbbbb", 结果是"b", 长度是1.

给定"pwwkew", 结果是 "wke", 长度是3. 注意答案应该是一个子串,"pwke" 是一个子序列而不是子串。


思路:

设立两游标,尾巴一直往后走,每遇到新字符就看看当前头尾间有没有出现过这个字符。出现过的话就去掉一个头部,再重复判断。没出现过的话就把这个字符加进来,子串变长1个单位,同时更新最大长度。整体思路好比一个能调节自身的毛毛虫在字符串上伸缩蠕动。

判断头尾间有没有出现过这个字符,这个要用哈希表来解决。由于此处哈希的key是单个字符,所以对c语言来说可以不使用较为复杂的uthash,而是使用长度超过128的数组代替,以char转int后作数组的下标作为key,数组的值作为value。


int lengthOfLongestSubstring(char* s) {
    int flag[130] = {0};
    char *p1 = s, *p2 = s;
    int maxlen = 0, len = 0;
    while ((*p1) && (*p2)){
        if (flag[*p2]){ //如果尾巴指的字符在子串中
            flag[*p1] = 0;  //去掉子串中的头部
            p1++;   //头部后移
            len--;  //子串变短
        }
        else{   //如果尾巴指的字符不在子串中
            flag[*p2] = 1;  //加入子串
            p2++;   //尾部后移
            len++;  //子串变长
            if (len > maxlen) maxlen = len; //更新最大值
        }
    }
    return maxlen;
}


class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        flag = {}   # 字符:存在
        p1, p2, lenString = 0, 0, len(s)
        maxlen, thislen = 0, 0
        while p1 < lenString and p2 < lenString:
            if s[p2] in flag:   # 如果尾巴所指字符在子串中
                del flag[s[p1]] # 删除子串的头部
                p1 += 1    # 头部后移
                thislen -= 1   # 子串变短
            else:   # 如果尾巴所指的字符不在子串中
                flag[s[p2]] = 1 #加入子串
                p2 += 1    # 尾部后移
                thislen += 1   # 子串变长
                if thislen > maxlen: maxlen = thislen   # 更新最大值
        return maxlen




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值