leetcode3无重复字符的最长字串(重点讲滑动窗口)

本文主要讲解无重复字符的最长字串的要点与细节,根据步骤一步步走更方便理解

c++与java代码如下,末尾

具体要点:

1. 区分一下子串和子序列

        子串:要求元素在母串中是连续地出现

        子序列:不要求连续


2. 题目中有两个核心要点:无重复,最长

        无重复:我们可以想到哈希表来解决(哈希表用来判断一个元素是否出现过)

        最长:我们可以利用滑动窗口的思路来解决(滑动窗口通常用来解决某种连续性子序列条件)


3. 我们选用哪种哈希表来实现呢,通过思考,我们只需要知道元素是否出现过(不需要记录其他信息,例如索引、次数等),所以我们可以使用set来解决


4. 解决了无重复的问题,我们思考一下滑动窗口具体应该怎么实现?

        滑动窗口通常都是两个指针,一个right一个left

        开始时我们先移动right,判断条件是:right始终不越界 + right的值始终没有出现过

即             while (right < s.size() && hashset.find(s[right]) == hashset.end())

        移动right并加入set中

即            hashset.insert(s[right]);
                right++;

        直到right不能再移动后,我们记录最大长度,并移动一次left,同时把left的值从set中删除 

即        //更新最大长度

            result = max(result, right - left);

            //删除left并移动left

            hashset.erase(s[left]);

            left++;

        至此,实现一轮滑动(每一轮都只移动一次left) 


c++代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int result = 0;
        //定义滑动窗口的两个指针
        int left = 0, right = 0;
        //定义一个set去重
        unordered_set<char> hashset;
        while (right < s.size()) {
            //不断移动right
            while (right < s.size() && hashset.find(s[right]) == hashset.end()) {
                hashset.insert(s[right]);
                right++;
            }
            //更新最大长度
            result = max(result, right - left);
            //移动left
            hashset.erase(s[left]);
            left++;
        }
        return result;
    }
};

java代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //滑动窗口
        int right = 0, left = 0;
        int result = 0;
        //定义set,防止重复
        HashSet<Character> map = new HashSet<Character>();
        //特殊情况0和1
        if (s.length() == 0 || s.length() == 1) {
            return s.length();
        }
        while (s.length() > right) {
            //right位置如果没有出现过,就add
            while (s.length() > right && !map.contains(s.charAt(right))) {
                map.add(s.charAt(right));
                right++;
            }
            result = Math.max(result, right - left);
            //right移动到不能移动,就开始移动left
            map.remove(s.charAt(left));
            left++;
        }
        return result;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值