zoukankan      html  css  js  c++  java
  • 3. 无重复字符的最长子串

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

    示例 1:

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

    示例 2:

    输入: "bbbbb"
    输出: 1
    解释: 无重复字符的最长子串是 "b",其长度为 1。
    

    示例 3:

    输入: "pwwkew"
    输出: 3
    解释: 无重复字符的最长子串是 "wke",其长度为 3。
         请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。

    解题思路
    用left和right设置左右指针,分别标识字符串不重复字段的左部和右部。右指针不断移动直到遇到重复字符,同事更新长度。
    当右指针所指元素已经查找过是,将左指针移到重复元素的后一位。

    方法一:
      用set方法,进而用contain判断是否重复
    class Solution {
        public int lengthOfLongestSubstring(String s) {
            int res = 0, left = 0, right = 0;
            //滑动窗口解法1:set结构
            Set<Character> set = new HashSet<>();
            while(right < s.length()){
                 //contains是包涵的意思,就是用来检查有没有在录入的连续的map里面
                if(!set.contains(s.charAt(right))){
                    set.add(s.charAt(right++));
                    res = Math.max(res,set.size());
                }else{
                    //左指针向右移动,直到移动到重复元素
                    set.remove(s.charAt(left++));
                }
            }
            return res;
        }
    }

    方法二:

      用的map方法,这里一开始没太弄懂,原来是吧left指针移至容器内的字符后一位,一开始理解错了。

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            //滑动窗口解法:map结构
            Map<Character,Integer> map = new HashMap<>();
            int res = 0;
            for(int left = 0, right = 0; right < s.length(); right++ ){
                if(map.containsKey(s.charAt(right))){
              //需要向后移至到重复字符后一位 left
    = Math.max(left, map.get(s.charAt(right)) + 1); } res = Math.max(res, right - left + 1); //根据map的性质,当存储重复元素时,新的value值即索引将会覆盖旧值 map.put(s.charAt(right), right); } return res;
    abcacs } }

    方法三:

      这里我们可以建立一个256位大小的整型数组来代替HashMap,这样做的原因是ASCII表共能表示256个字符,所以可以记录所有字符,然后我们需要定义两个变量res和left,其中res用来记录最长无重复子串的长度,left指向该无重复子串左边的起始位置,然后我们遍历整个字符串,对于每一个遍历到的字符,如果哈希表中该字符串对应的值为0,说明没有遇到过该字符,则此时计算最长无重复子串,i - left +1,其中i是最长无重复子串最右边的位置,left是最左边的位置,还有一种情况也需要计算最长无重复子串,就是当哈希表中的值小于left,这是由于此时出现过重复的字符,left的位置更新了,如果又遇到了新的字符,就要重新计算最长无重复子串。最后每次都要在哈希表中将当前字符对应的值赋值为i+1。代码如下:

    class Solution {
        public int lengthOfLongestSubstring(String s) {
         //滑动窗口方法:数组存储ASCII值
            int[] m = new int[256];
            int res = 0;
            //try extend the rang [left, right]
            for(int left = 0, right = 0; right < s.length(); right++){
                //m[s.charAt(right)]返回一个重复字符的地址
                left = Math.max(m[s.charAt(right)], left);
                res = Math.max(res, right - left + 1);
                m[s.charAt(right)] = right + 1;
            }
            return res;
        }
    }

    分析表格

    0 1 2 3 4 5 6
    a b c a b c a


    right left res
    m[s.charAt(right)]
    0 0 1 1
    1 0 2 2
    2 0 3 3
    3 1 3 4
    4 2 3 5


  • 相关阅读:
    记录一下自己写PHP程序时走过的一些坑
    自己写了一个TCP攻击测压平台
    Centos 7x 安装 Telegram MTproxy代理【完美可用】
    "@阅后即焚"上线了!
    小白的机器学习坑3:粗大的安装CUDA
    小白的机器学习坑2:nvidia驱动的安装
    小白的机器学习坑1:ubuntu 18.04的安装
    小白的linux学习笔记9:安装nodejs和gitbook
    小白的linux笔记11:放弃gitbook,转战Sphinx
    小白的linux学习笔记10:安装nginx和第一个网页
  • 原文地址:https://www.cnblogs.com/xiemingjun/p/9636343.html
Copyright © 2011-2022 走看看