Sword48——最长不含重复字符的子字符串

Sword48——最长不含重复字符的子字符串

方法1——动态规划+哈希表

  • 思路:使用Map记录已出现字符的最新下标,当再次遍历到相同字符时,计算其无重复字符子串的长度即可
  • 特殊情况与临界分析:无
  • 终止条件:遍历到最后一个字符完成操作
  • 步骤:
    • 将字符串转换为字符数组
    • 定义Map存储字符及其对应下标
    • 定义结果值、临时值
    • for循环
      • 参数:i从0开始,i小于字符数组长度
      • 判断当前字符是否在Map中出现过,出现获取其下标,未出现获取为-1
      • 将当前字符及其下标加入Map,即更新哈希表
      • 获取此时以当前字符结尾的最长无重复子串长度
        • 判断以当前字符结尾的字符串长度(i - 原字符下标),是否比之前的最长无重复子串要长
        • 如果要长,则结果为最长无重复子串加1
        • 否则即为i - 原字符下标
      • 更新最长无重复字符的结果
      • 返回结果
    public int lengthOfLongestSubstring(String s) {
        // 将字符串转换为字符数组
        char[] chars = s.toCharArray();
        // 定义Map,用于存储字符即字符对应下标
        Map<Character, Integer> dic = new HashMap<>();
        // 定义结果值、临时子串长度值
        int res = 0, tmp = 0;
        // for循环
        for (int i = 0; i < chars.length; i++) {
            // 获取当前字符出现过的索引位置,未出现则为-1
            int index = dic.getOrDefault(chars[i], -1);
            // 更新哈希表
            dic.put(chars[i], i);
            // 判断以当前字符结尾的最长无重复子串长度
            // if (i - index > tmp) {
            //     tmp = i - index;
            // } else {
            //     tmp += 1;
            // }
            // 三元运算符写法
            tmp = (tmp < i - index) ? (tmp + 1) : (i - index);
            // 更新最长无重复子串的结果
            res = Math.max(res, tmp);
        }
        // 返回结果值
        return res;
    }

方法1——动态规划+哈希表

方法2——单指针+哈希表

  • 思路:定义左指针从-1开始,使用Map记录已出现字符的下标,并计算最长无重复子串,当再次遍历到相同字符时,更新左指针
  • 特殊情况与临界分析:无
  • 终止条件:遍历到最后一个字符完成操作
  • 步骤:
    • 将字符串转换为字符数组
    • 定义Map存储字符及其对应下标
    • 定义结果值、左指针
    • for循环
      • 参数:i从0开始,i小于字符数组长度
      • 判断当前字符是否在Map中出现过
        • 出现则更新左指针,取当前位置与出现过的下标的最大值
        • 这里取二者的最大值原因:是因为防止之前出现过此字符,导致更新后左指针回退
      • 将当前字符及其下标加入Map,即更新哈希表
      • 更新最长无重复字符的结果
      • 返回结果
    public int lengthOfLongestSubstring(String s) {
        // 将字符串转换为字符数组
        char[] chars = s.toCharArray();
        // 定义Map
        Map<Character, Integer> dic = new HashMap<>();
        // 定义结果值、左指针
        int res = 0, left = -1;
        // for循环
        for (int i = 0; i < chars.length; i++) {
            // 判断当前字符是否出现过
            if (dic.containsKey(chars[i])) {
                // 更新左指针
                left = Math.max(left, dic.get(chars[i]));
            }
            // 将当前字符及其下标加入Map
            dic.put(chars[i], i);
            // 更新最长无重复子串的长度
            res = Math.max(res, i - left);
        }
        // 返回结果
        return res;
    }

方法2——单指针+哈希表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值