题目信息

  • 时间: 2019-07-02

  • 题目链接:Leetcode

  • tag: 动态规划 哈希表

  • 难易程度:中等

  • 题目描述:

    请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例1:

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

示例2:

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

示例3:

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

注意

1. s.length <= 40000

解题思路

本题难点

长度为 N 的字符串共有 (1+N)N/2 个子字符串(复杂度为 O(N^2 ) ),判断长度为 N 的字符串是否有重复字符的复杂度为 O(N) ,使用暴力法解决的复杂度为 O(N^3) 。

具体思路

考虑使用动态规划降低时间复杂度。

  • 状态定义:设动态规划列表 dp ,dp[j] 代表以字符 s[j 为结尾的 “最长不重复子字符串” 的长度。
  • 转移方程:固定右边界 j ,设字符 s[j] 左边距离最近的相同字符为 s[i] ,即 s[i]=s[j] 。
    • 当 i<0时,即 s[j] 左边无相同字符,则 dp[j]=dp[j−1]+1 ;
    • 当 dp[j−1] < j−i 时,说明字符 s[i] 在子字符串 dp[j−1] 区间之外 ,则 dp[j]=dp[j−1]+1 ;
    • 当 dp[j−1] > j−i 时,说明字符 s[i] 在子字符串 dp[j−1] 区间之中 ,则 dp[j] 的左边界由 s[i] 决定,即 dp[j]=j−i ;

注意:当 i<0 时,由于 dp[j−1]≤j 恒成立,因而 dp[j−1]<j−i 恒成立,因此分支 1. 和 2. 可被合并。

代码

class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> dic = new HashMap<>();
int res = 0, tmp = 0;
for(int j = 0; j < s.length(); j++) {
int i = dic.getOrDefault(s.charAt(j), -1); // 获取索引 i
dic.put(s.charAt(j), j); // 更新哈希表
tmp = tmp < j - i ? tmp + 1 : j - i; // dp[j - 1] -> dp[j]
res = Math.max(res, tmp); // max(dp[j - 1], dp[j])
}
return res;
}
}

复杂度分析:

  • 时间复杂度 O(N) :其中 N为字符串长度,动态规划需遍历计算 dp列表。
  • 空间复杂度 O(1) : 字符的 ASCII 码范围为 0 ~ 127 ,哈希表 dic 最多使用 O(128)=O(1) 大小的额外空间。

其他优秀解答

解题思路

双指针 + 哈希表

哈希表 dic统计: 指针 j遍历字符 s,哈希表统计字符 s[j]最后一次出现的索引

更新左指针 i : 根据上轮左指针 i 和 dic[s[j]] ,每轮更新左边界 i ,保证区间 [i+1,j] 内无重复字符且最大

更新结果 res : 取上轮 res 和本轮双指针区间 [i+1,j] 的宽度(即 j−i )中的最大值。

代码

class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character,Integer> dic = new HashMap<>();
int i = -1,res = 0;
//遍历字符串 s
for(int j = 0; j < s.length();j++){
//遍历到 s[j] 时,可通过访问哈希表 dic[s[j]] 获取最近的相同字符的索引 i
if(dic.containsKey(s.charAt(j))){
//取最大值因为防止abba的情况出现
i = Math.max(i,dic.get(s.charAt(j)));
}
//使用哈希表统计 各字符最后一次出现的索引位置
dic.put(s.charAt(j),j);
res = Math.max(res,j-i);
}
return res;
}
}

每日一题 - 剑指 Offer 48. 最长不含重复字符的子字符串的更多相关文章

  1. 剑指 Offer 48. 最长不含重复字符的子字符串 + 动态规划 + 哈希表 + 双指针 + 滑动窗口

    剑指 Offer 48. 最长不含重复字符的子字符串 Offer_48 题目详情 解法分析 解法一:动态规划+哈希表 package com.walegarrett.offer; /** * @Aut ...

  2. 【Java】 剑指offer(48) 最长不含重复字符的子字符串

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字 ...

  3. 剑指 Offer 48. 最长不含重复字符的子字符串

    题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度. 示例1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 & ...

  4. 剑指offer——50最长不含重复字符和子字符串

    题目: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含’a~z”的字符.例如,在字符串“arabcacfr"中,最长的不含重复字符的子字符串 ...

  5. 剑指offer-面试题48-最长不含重复字符的子字符串-动态规划

    /* 题目: 最长不含重复字符的子字符串. */ /* 思路: f(i) = f(i-1) + 1,(未出现过当前字符,distance > f(i-1) distance,当前字符和上一次出现 ...

  6. 剑指offer面试题48: 最长不含重复字符的子字符串

    Given a string, find the length of the longest substring without repeating characters.(请从子字符串中找出一个最长 ...

  7. 《剑指offer》面试题48. 最长不含重复字符的子字符串

    问题描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.   示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串 ...

  8. 《剑指offer》第四十八题(最长不含重复字符的子字符串)

    // 面试题48:最长不含重复字符的子字符串 // 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子 // 字符串的长度.假设字符串中只包含从'a'到'z'的字符. #inclu ...

  9. 【Offer】[48] 【最长不含重复字符的子字符串】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含'a'~'z'的字符.例如,在字符串&q ...

随机推荐

  1. Java实现 LeetCode 29 两数相除

    29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...

  2. Java实现行列递增矩阵的查找

    1 问题描述 在一个m行n列的二维数组中,每一行都按照从左到右递增的顺序排列,每一列都按照从上到下递增的顺序排列.现在输入这样的一个二维数组和一个整数,请完成一个函数,判断数组中是否含有该整数. 2 ...

  3. Java实现 蓝桥杯 历届试题 大臣的旅费

    问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首 ...

  4. java实现第四届蓝桥杯梅森素数

    梅森素数 题目描述 如果一个数字的所有真因子之和等于自身,则称它为"完全数"或"完美数" 例如:6 = 1 + 2 + 3 28 = 1 + 2 + 4 + 7 ...

  5. 【CSS】电脑、移动端公用样式

    电脑端: /* Public */ @charset "utf-8"; html, body, div, p, ul, ol, li, dl, dt, dd, h1, h2, h3 ...

  6. Fiddler13模拟弱网络环境测试

    前言现在的Android软件,基本上都会有网络请求,有些APP需要频繁的传输数据时对于网络请求的稳定性和在特殊网络条件下的兼容性有要求,但是我们在测试的时候又很难模拟那种弱网络差网络的情况,今天就给大 ...

  7. 注解实现SpringCache自定义失效时间

    注解实现SpringCache自定义失效时间 SpringCache是一个很方便的缓存框架,但是官方提供的缓存的配置只有全局的缓存失效时间,没有针对某个命名空间做配置,因为工作上业务的关系需要针对某一 ...

  8. Clear Writer v1.8 更新

    拖更了这么久之后,Clear Writer 诈尸啦(bushi 下载链接:https://linhongping.lanzous.com/ikF2Udmf7if Clear Writer v1.8 更 ...

  9. (五)POI-设置单元格的对齐方式

    原文链接:https://blog.csdn.net/class157/article/details/92817149 package com.java.poi; import org.apache ...

  10. cb35a_c++_STL_算法_for_each

    cb35a_c++_STL_算法_for_each for_each(b,e,p)使用for_each()算法遍历数据使用for_each()和函数对象修改数据使用for_each()的返回值 //转 ...