Problem03 无重复的最长子串

无重复的最长子串>>>

在这里插入图片描述

滑动窗口:定义一个窗口left---rightleft----right这个窗口内元素是不重复的,不断移动right并将其值存入hashMap中,方便进行去重,使用hashMap.contains(key)即可判断在当前移动到的位置是否包含了之前窗口中的位置,若发现需要移动窗口的左边在更新左边界的位置lefty=Math.max(lweft,map.get(s.char(i)+1)

package KTwoPointers;

import AarrayProblem.Problem1;

import java.util.HashMap;
import java.util.HashSet;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/5/7 0007  11:59
 */
public class Problem3 {


    //https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/
    //采用动态规划
    //无重复的最长子串
    //dp[i]为 字符串的前i个元素怒中的最长无重复
    //dp[i] dp[i-1]
    public int lengthOfLongestSubstring(String s) {

        if(s==null||s.length()==0) return 0;

        int[] dp = new int[s.length()];
        dp[0]=1;

        for(int i=1;i<s.length();i++){
            //默认的最长子串为自身
            dp[i]=1;

            for(int j=0;j<i;j++){
                dp[i]=Math.max(dp[i],dp[j]);
            }

            //从当前位置向前遍历找,查找在这个位置开始向前树的连续不重复字符串
            int rs = 1;
            int j = i-1;
            while (j>=0){
                if(s.substring(j+1,i+1).contains(s.charAt(j)+"")) break;
                else {
                    rs++;
                    j--;
                }
            }
            //更新dp[i]
            dp[i]=Math.max(dp[i],rs);
        }

        int max = 0;
        for(int i=0;i<s.length();i++) max = Math.max(max,dp[i]);
        return max;

    }


    //这道题主要用到的思想就是:滑动窗口
    //什么是滑动窗口》
    //其实就是一个队列,比如例题中的abcabcbb
    //进入这个队列(窗口)为abc满足题目要求。当在进入a时,这时候不满足要求。
    // 所以我们要移动这个队列!!!
    // 如何移动?
    //我们只要把队列的左边的元素移动出来就行了,直到满足题目要求!!!!
    //一直维持这样的队列,找出队列最长的长度的时候,求出街
    public int lengthOfLongestSubstring1(String s){

        if(s.length()==0) return 0;

        HashMap<Character,Integer> map = new HashMap<>();

        int max = 0;
        //左侧
        int left = 0;

        for(int i=0;i<s.length();i++){

            //在map中包含了i处的元素,则需要移动 left指针
            //移除左边界移动到重复元素的下一个,就是此时重复元素左边的元素全部抛弃掉了
            //加这个left是确保左侧已经遍历过的数据就不需要再次遍历了,确保不断向右侧遍历
            if(map.containsKey(s.charAt(i))){
                //在这里可能需要更新也可能不需要更新
                //若左边界大于 map中发现包含的重复字符则不需要更细
                //否则更新
                left = Math.max(left,map.get(s.charAt(i))+1);
            }
            
            //将遍历到窗口中的值
            map.put(s.charAt(i),i);
            max = Math.max(i-left+1,max);
        }

        return max;


    }

    public static void main(String[] args) {
        String s = "abba";
        Problem3 problem3 = new Problem3();
        System.out.println(problem3.lengthOfLongestSubstring1(s));
    }


}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值