Leetcode_3_无重复字符的最长子串_map

本文介绍了一种求解字符串中最长无重复字符子串长度的算法。通过使用哈希表跟踪字符位置,实现滑动窗口更新最长子串。逐步优化代码效率,从基本实现到使用ASCII码简化数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

12/10

遍历字符串
维护一个临时字符串和最长子串的长度
临时字符串将尝试所有连续无重复字符的情况。
用hashmap保存各个字符上次出现的下标
若遍历到的字符又出现,将目前的字符串的头指针移动到该字符上次出现的后一位
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int ans=0;
        int now=0;
        int st=0;
        Map<Character,Integer>mp=new HashMap<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            if(mp.containsKey(ch)==false){
                now++;
            }else{
                int fin=mp.get(ch);
                for(int j=st;j<fin;j++){
                    mp.remove(s.charAt(j));
                }
                now-=fin-st;
                st=fin+1;
            }
            mp.put(ch,i);
            ans=Math.max(ans,now);
        }
        return ans;
    }
}

简单优化

不需要每次修改临时字符串的起点时,删除旧起点和新起点之间的映射关系。我们只需要保存上一次该字符出现的下标位置。
若是检测到的key的value小于st那么,就代表他已经不在临时字符串中,滑动窗口的左侧直接跳跃
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int ans = 0;
        int now = 0;
        int st = 0;
        Map<Character, Integer> mp = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (mp.getOrDefault(ch, -1) < st) {
                now++;
            } else {
                int fin = mp.get(ch);
                now -= fin - st;
                st = fin + 1;
            }
            mp.put(ch, i);
            ans = Math.max(ans, now);
        }
        return ans;
    }
}

再优化:hashmap变字符串,index为ascll码

通过下标+1来规避掉下标为0的情况

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int ans = 0;
        int now = 0;
        int st = 0;
        int[] asc = new int[128];
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (asc[ch] - 1 < st) {
                now++;
            } else {
                int fin = asc[ch] - 1;
                now -= fin - st;
                st = fin + 1;
            }
            asc[ch] = i + 1;
            ans = Math.max(ans, now);
        }
        return ans;
    }
}

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值