3-无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣(LeetCode) (leetcode-cn.com)

题目

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入: s = ""
输出: 0
思路

双指针l,r res记录最大子串的长度

遍历r;l用于记录窗口最左端的值,当r当前遍历的值和l相同时,l更新

r每移动一次就更新一次res

当遇到重复元素,左指针如何更新

光l++没用,如果当前子列的重复元素不在最左端而是在中部呢
因此每次遍历需记录 下一次遍历时 碰到重复元素 左指针该更新的位置

采用哈希表

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //哈希表记录遍历的每一个值.键:字符串元素  值:下标
        Map<Character,Integer> map = new HashMap<Character, Integer>();
        char[] num = s.toCharArray();

        /*定义属性
        * i 左指针
        * j 右指针
        * max   记录结果 子串长度最大值
        * */
        int res = 0;
        for(int i=0,j=0;j<s.length();j++){

            //若右指针所指元素x已经存在于map,更新左指针至map中x的所对应的下标的后一位
            if(map.containsKey(num[j])){
                i = Math.max(i,map.get(num[j]) + 1);
            }

            //判断当前元素是否包含在map中,若不包含,put进map、更新max
            //每次都要更新num[j](右指针所指元素)在map中的最新位置
            map.put(num[j],j);
            res = Math.max(res,j-i+1);

       }
        return res;

    }
}

17行代码解释

如果当前字符 ch 包含在 map中,此时有2类情况:
1)当前字符包含在当前有效的子段中,如:abca,当我们遍历到第二个a,当前有效最长子段是 abc,我们又遍历到a,那么此时更新 left 为 map.get(a)+1=1,当前有效子段更新为 bca;
2)当前最长有效子段不包含当前字符,如:abba,我们先添加a,b进map,此时left=0,我们再添加b,发现map中包含b,而且b包含在最长有效子段中,就是1)的情况,我们更新 left=map.get(b)+1=2,此时子段更新为 b,而且map中仍然包含a,
此时当前最长子段"b"不包含当前字符a.
map.get(a)=0;随后,我们遍历到a,发现a包含在map中,且map.get(a)=0,如果我们像1)一样处理,就会发现 left=map.get(a)+1=1,实际上,left此时应该不变,left始终为2,子段变成 ba才对。

为了处理以上2类情况,我们每次更新left,left=Math.max(left , map.get(ch)+1).另外,更新left后,不管原来的 s.charAt(i) 是否在最长子段中,我们都要将 s.charAt(i) 的位置更新为当前的i,因此此时新的 s.charAt(i) 已经进入到当前最长的子段中!

当检索到重复时 获取重复的坐标和start比较 如果小于start则相当于忽略重复 然后在结尾的又一次put就更新了hash表

其他优解

直接比较ASCII码的方法,不明白char和int的本质,debug后了解

image-20210928171545051
详谈char和int

string对象是不可变的,值不会发生变化

string类不是原始数据类型,我们学习的很多算法都能处理字符串的低级表示,如char类型的数组(消耗空间小,访问时间少)

image-20210928163107780

​ 字符型数据在内存中是以二进制形式存放的,并不是真正的把一个字符存进内存里。在对字符型数据进行相加减运算的时候,系统会首先将char型数据以隐形的方式转化为int型数据再进行相加减运算。因此,由字符型数据在内存的存储方式来看,字符型数据在做数字运算时实际上是对字符本身对应的ASCII码进行相应的数值运算。

​ 既然char和int本质都是整数,为什么还要作区分呢?

因为字符的个数相对较少,因而char型变量的存储单元可以比int型变量的存储单元小。其实就是提出一种char型变量专门存储字符,方便程序员的数据选择。

‘A’ 65 ‘a’ 97 相差32

Ascii码

[(10条消息) ASCII码字符对照表_会飞的鱼的博客-CSDN博客_ascii码对照表](

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值