[LeetCode] 无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 无重复字符的最长子串是 "abc",其长度为 3。

解法1

建立一个256位的整型数组,因为ASCII表能表示256位字符,这样我们可以记录所有的字符,然后定义两个变量res和left,res用来记录最长无重复子串的长度,left记录该无重复子串左边的起始位置,然后我们遍历整个字符串,对于每一个遍历的字符,如果数组中的值为0,表示之前还没遇到该字符,此时需要计算最长无重复子串,即最右边减去最左边的长度(i-left+1),i表示最右边,left表示最左边

还有一种情况也要考虑,由于此时出现重复的字符,left的位置也更新了,如果又遇到该字符,需要重新计算最长无重复子串.

        static int LengthOfLongestSubstring1(string s)
        {
            int[] m = new int[256];
            for (int i = 0; i < m.Length; i++)
            {
                m[i] = 0;
            }
            int res = 0, left = 0;
            for (int i = 0; i < s.Length; i++)
            {
                if (m[s[i]] == 0 || m[s[i]] < left)
                {
                    res = Math.Max(res, i + 1 - left);
                }
                else
                {
                    left = m[s[i]];
                }
                m[s[i]] = i + 1;
            }
            return res;
        }

解法2

简化解法1的操作

        static int LengthOfLongestSubstring2(string s)
        {
            int[] m = new int[256];
            for (int i = 0; i < m.Length; i++)
            {
                m[i] = 0;
            }
            int res = 0, left = 0;
            for (int i = 0; i < s.Length; i++)
            {
                //当m[s[i]]不为0,说明该字符已经出现过了,可能需要变化left的位置了
                left = Math.Max(left, m[s[i]]);
                m[s[i]] = i + 1;
                //i+1-left:表示的是最右边的减去最左边的长度
                res = Math.Max(res, i + 1 - left);
            }
            return res;
        }

解法3

使用HashSet来表示,把出现的字符存放到set中,遇到set中没有出现过的,加入到set中,并更新res的值,如果遇到重复的了,则从左边开始删字符,直到删除到重复的字符停止

static int LengthOfLongestSubstring3(string s)
{
    int res=0,left=0,right=0;
    HashSet<int> set=new HashSet<int>();
    while(right<s.Length)
    {
         if(!set.Contains(s[right]))
         {
            set.Add(s[right++]);
            res=Math.Max(res,set.Count);
         }   
         else
            set.Remove(s[left++]);
    }
    return res;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值