卜若的代码笔记-算法系列-第八个算法案例分析:无重复字符的最长子串

常规的解法是:

比如一个字符串abcabcbb

每一次截取一段

abcabcbb->捕捉不重复串 = abc

bcabcbb->捕捉不重复串 = bca

cabcbb->...

abcbb->...

bcbb.->...

,,,

最后将所有不重复串填塞到一个表里面

获取这个表中最长串的长度返回:

/*
 * @lc app=leetcode.cn id=3 lang=java
 *
 * [3] 无重复字符的最长子串
 */

// @lc code=start
class Solution {
    public int lengthOfLongestSubstring(String s) {


        // System.out.println("hello world");
        if(s.length() == 0){

            return 0;
        }
        char[] ca = s.toCharArray();
        int len = 0;
        int lastChar = ca[0];
        List<point> li = new ArrayList<point>();
        for(int i =0;i<ca.length;i++){
            point p1 = new point();
            for(int j =i;j<ca.length;j++){

                if(!p1.charArr.contains(ca[j])){
                    p1.charArr.add(ca[j]);
                }
                else{
                    break;
                }
            }
            li.add(p1);
        }
        int max = li.get(0).charArr.size();
        for(int i =0;i<li.size();i++){

            System.out.println(li.get(i).charArr.size());
            if(max < li.get(i).charArr.size()){

                max = li.get(i).charArr.size();
            }
        }


        return max;
    }

    class point{
        public List<Character> charArr = new ArrayList<Character>();
    }
}
// @lc code=end

效率感人:

我搜索了一下别人优秀的解法,然后,他们的角度及其刁钻,我写一下解题思路:

比如ababvd

 

1.动态的获取start的位置

2.长度等于当前遍历索引index - start +1(从0开始算起索引索引添加1)

当start = 0时

index = 0时,子串长度(sl)为1

index = 1时,子串长度为2

index = 2时,这个时候,我们观测到子串结构为aba,显然是一个重复子串,所以,start就应该变了应该拒绝掉上一个重复字符的位置,也就是start = 1,子串编程ba

index = 3时,子串为bab,显示是一个重复子串,start应该往前走一步为ab,sl = 2

index = 4时,子串为abv,sl = 3

index = 5时,子串为abvd sl = 4

接下来我们分析一下其他特殊情况

子串sstr,子串长度sl

1.s = pwwkew

start = 0;

index = 0,sl = 1,sstr = p

index =1,sstr = pw,sl = 2;

index = 2,sstr = pww ->start = 上一个w的位置+1的位置也就是 start = 2;sstr = w,sl = 1

index = 3,sstr = wk,sl = 2

...

2.s = abba

start = 0

index = 0,sstr = a

index = 1,sstr = ab

index = 2,sstr = abb ->start = 2,sstr = b

index = 3,sstr = ba ->start = 1,sstr =bba

显然,我们发现index = 3时,就会出问题,因为这个时候,start肯定不能网前移,只能网后推,通常情况下我们需要加一个max

 

 

以下是源码:

/*
 * @lc app=leetcode.cn id=3 lang=java
 *
 * [3] 无重复字符的最长子串
 */

// @lc code=start
class Solution {
    public int lengthOfLongestSubstring(String s) {

        HashMap<Character,Integer> map = new HashMap<>();
        List<Integer> lenList = new ArrayList<>();
        char[] ca = s.toCharArray();
        int max = 0;

        //考虑到字符串只有1的情况

        if(s.length() <= 1){

            return s.length();

        }
        int start = 0;
        for(int i =0;i<ca.length;i++){
            

            if(map.containsKey(ca[i])){

                start = Math.max(map.get(ca[i])+1,start);
            }
            
            map.put(ca[i],i);          
            int sl = i - start+1;
            lenList.add(sl);
            
            
        }

        for(int i =0;i<lenList.size();i++){
            if(max<lenList.get(i)){

                max = lenList.get(i);
            }
            // System.out.println(lenList.get(i));

        }
        
        return max;
    }

   
}
// @lc code=end

效率提升了很多,当然,效率还能提高,比如取消掉lenList,直接max,当然,这些细节的东西可以自己琢磨

 

 

总结下来就是:

 

start为起始,索引为终点的窗口扫过这组数据,判断节点重复,更新start从而更新不重复窗口。

时间复杂度是o(n)。

时间复杂度是o(n),上面的时间复杂度是o(n2)

...真特么diao

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值