Leecode刷题笔记——第三题

题目:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

本来想整个滑动窗口,但是因为各种特殊情况,就一直不对,最好的滑动窗口的版本如下:

public class Solution
{
    public int LengthOfLongestSubstring(string s)
     {
        char[] sChar = s.ToCharArray();//将字符串变为字符型数组
        int Window = 0; //定义滑动窗口
        int MaxLength = 0; //定义最长不重复字符串长度
        char[] LongestStr = new char[sChar.Length];
        //确定窗口大小(字符串中一共有多少个不同字符)
        for(int i = 0;i<sChar.Length;i++)
        {
            if(Array.IndexOf(LongestStr,sChar[i])<0)
            {
                LongestStr[Window] = sChar[i];
                Window++;
            }
        }
        //求最大长度
        for(int j=0;j<(sChar.Length-Window+1);j++)
        { 
            char[] ResStr = new char[sChar.Length];
            int Length = 0;
            for (int m=0;m<Window;m++)
            {
                if(Array.IndexOf(ResStr,sChar[j+m])<0)
                {
                    Length++;
                    ResStr[Length-1]=sChar[j+m];
                }
                else break;
            }  
            if(Length>=MaxLength)
            {
                MaxLength = Length;
            } 
        } 
        return MaxLength;      
    }
}

但即便这样,还是没能通过所有的测试用例

然后发现思路的确有问题,就是滑动窗口还是不能遍历所有的情况 

 于是,开始想别的方法🤔

既然滑动窗口会漏掉情况,就想干脆就不要滑动了,改变窗口大小

public class Solution
{
    public int LengthOfLongestSubstring(string s){
        char[] sChar = s.ToCharArray();//将字符串变为字符型数组
        int MaxLength=0;
        for (int i=0;i<sChar.Length;i++)
        {
            int Length = 0;
            char[] ResStr = new char[sChar.Length];
            for(int j=0;i+j<sChar.Length;j++)
            {
                if(Array.IndexOf(ResStr,sChar[i+j])<0)
                {
                    Length++;
                    ResStr[Length-1]=sChar[i+j];
                }
                else break;
            }
            if(Length>=MaxLength)
            {
                MaxLength = Length;
                Length = 0;
            } 
        }  
        return MaxLength;     
    }
        
}

思路很简单粗暴:

但是没想到,这次又变了个花样得不过:

 看来大力不能出奇迹🤔 不能牺牲时间来保全情况完整

挣扎了很久之后,最终,我还是借鉴了前辈的经验,原来代码可以很简洁😂

public class Solution
{
    public int LengthOfLongestSubstring(string s){
            int i = 0;
            int j = 0;
            int maxLength=0;
            char[] cs = s.ToCharArray();
            int n = s.Length;
            HashSet<char> cSet = new HashSet<char>();
            while (i < n && j < n)
            {
                if (!cSet.Contains(cs[j]))
                {
                    cSet.Add(cs[j]);
                    j++;
                    maxLength = Math.Max(maxLength, j - i);
                }
                else
                {
                    cSet.Remove(cs[i]);
                    i++;
                }
            }
            return maxLength;
        }
   
}

HashSet是一个散列表,里头用于存储不重复的值

i和j相当于两个指针,分别指向窗口的头和尾,通过改变i和j指向来滑动窗口

当没有遇到重复值的时候,就往cset中存入值,并移动j;当遇到重复值的时候,就删除cset中i对应的值,并往后移动i

其本质上,就是利用i和j当作一个大小可变的窗口,框出cs中的一段字符串,看这个范围中有没有重复的值,用这样的方式来找出最长不重复子串

重要思路步骤:利用i和j,截取cs字符串中的一段字符 

果然该用的东西还是要用起来,指针的思路在这题中就很有用,暴力解决是不行的 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值