码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 3. 无重复字符的最长子串--每天刷一道leetcode系列!

时间:2020-12-10 10:37:04      阅读:1      评论:0      收藏:0      [点我收藏+]

标签:因此   大小   题目   public   ng2   value   数据   nta   必须   

leetcode 3. 无重复字符的最长子串--每天刷一道leetcode系列!

技术图片

作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人

前文回顾:
leetcode1. 两数之和--每天刷一道leetcode系列!
leetcode2.两数相加--每天刷一道leetcode系列!

题目描述

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

示例 1:

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

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

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

分析

本题是一个典型的滑动窗口类题目,要求滑动窗口里没有重复的字符。
那么怎么滑动呢?

首先,我们需要用一个数据结构来记录窗口中的字符(可以是数组或者map,这个具体代码的时候再说)。

何时窗口右移?如果要处理的那个字符在滑动窗口里没有,那么窗口就可以右移了。因为此时还是能保证窗口里没有重复的字符。

窗口何时左移?如果要处理的那个字符在滑动窗口里有,那么窗口就需要左移。

左移什么时候结束?当左移到滑动窗口里面已经没有要处理的那个字符就可以结束了。
什么时候无重复子串最长?窗口最大的时候最长。

因此,回到刚才用来记录的数据结构那个问题,如果用数组怎么做?用数组的话,可以申请一个大小为256的数组,

当某个字符被加进滑动窗口,其对应位置的数就加1,当某个字符被移除滑动窗口,其对应位置的数就减1.

什么时候代表滑动窗口里面有这个字符?当其对应位置的值不为0就代表滑动窗口里面有这个字符了。

如果用map怎么做?可以用Mapmap来存储窗口中的值,key表示存储的字符,value表示存储的字符在已经遍历到的最右边的位置。用l表示滑动窗口的左端。

当map里包含要处理的字符的时候,此时窗口的最左边应该是l和map.get(c) + 1的较大者。当map里不包含要处理的字符的时候,此时窗口的最左边任然为l。
最后将待处理字符加入map并计算窗口大小。

代码

public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int[] tmp = new int[256];
        int maxLen = 0;
        int l = 0;
        int r = 0;

        while (l < s.length()) {
            if (r < s.length() && tmp[s.charAt(r)] == 0) {
                tmp[s.charAt(r++)] = 1;
            } else {
                maxLen = maxLen > (r - l) ? maxLen : (r - l);
                tmp[s.charAt(l++)] = 0;
            }
        }
        return maxLen;
    }

    public int lengthOfLongestSubstring2(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int maxLen = 0;
        int l = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            Character c = s.charAt(i);
            if (map.containsKey(c)) {
                l = l > (map.get(c) + 1) ? l : (map.get(c) + 1);
            }
            map.put(c, i);
            maxLen = maxLen > (i - l + 1) ? maxLen : (i - l + 1);
        }
        return maxLen;
    }

leetcode 3. 无重复字符的最长子串--每天刷一道leetcode系列!

标签:因此   大小   题目   public   ng2   value   数据   nta   必须   

原文地址:https://blog.51cto.com/15047485/2559859

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!