每日一题 - 剑指 Offer 48. 最长不含重复字符的子字符串
题目信息
时间: 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. 最长不含重复字符的子字符串的更多相关文章
- 剑指 Offer 48. 最长不含重复字符的子字符串 + 动态规划 + 哈希表 + 双指针 + 滑动窗口
剑指 Offer 48. 最长不含重复字符的子字符串 Offer_48 题目详情 解法分析 解法一:动态规划+哈希表 package com.walegarrett.offer; /** * @Aut ...
- 【Java】 剑指offer(48) 最长不含重复字符的子字符串
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字 ...
- 剑指 Offer 48. 最长不含重复字符的子字符串
题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度. 示例1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 & ...
- 剑指offer——50最长不含重复字符和子字符串
题目: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含’a~z”的字符.例如,在字符串“arabcacfr"中,最长的不含重复字符的子字符串 ...
- 剑指offer-面试题48-最长不含重复字符的子字符串-动态规划
/* 题目: 最长不含重复字符的子字符串. */ /* 思路: f(i) = f(i-1) + 1,(未出现过当前字符,distance > f(i-1) distance,当前字符和上一次出现 ...
- 剑指offer面试题48: 最长不含重复字符的子字符串
Given a string, find the length of the longest substring without repeating characters.(请从子字符串中找出一个最长 ...
- 《剑指offer》面试题48. 最长不含重复字符的子字符串
问题描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串 ...
- 《剑指offer》第四十八题(最长不含重复字符的子字符串)
// 面试题48:最长不含重复字符的子字符串 // 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子 // 字符串的长度.假设字符串中只包含从'a'到'z'的字符. #inclu ...
- 【Offer】[48] 【最长不含重复字符的子字符串】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含'a'~'z'的字符.例如,在字符串&q ...
随机推荐
- java实现算年龄
英国数学家德摩根出生于19世纪初叶(即18xx年). 他年少时便很有才华.一次有人问他的年龄,他回答说: "到了x的平方那年,我刚好是x岁". 请你计算一下,德摩根到底出生在哪一年 ...
- Java实现第十届蓝桥杯外卖店优先级
试题 G: 外卖店优先级 时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分 [问题描述] "饱了么"外卖系统中维护着 N 家外卖店,编号 1 ∼ N.每家外卖店 ...
- 流程图(HTML5拖拽)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)
作者:小傅哥 博客:https://bugstack.cn - 编写系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为什么你的代码那么多ifelse 同类的业务.同样的功能, ...
- vue之 :model和v-model的区别
v-model通常用于input的双向数据绑定 <input v-model="parentMsg">,也可以实现子组件到父组件数据的双向数据绑定 :model是v-b ...
- mysql基础-数据库表简单查询-记录(五)
0x01 MySQL的查询操作 单表查询:简单查询 多表查询:连续查询 联合查询 选择和投影 投影:挑选要符合的字段 select ...
- matplotlib 示例
示例1 import numpy as np import matplotlib.pyplot as plt #plt.rcParams['font.family'] = ['sans-serif'] ...
- 2019-02-07 selenium...
今天是超级郁闷的一天 看教程 下了mysql-----配置-----不会----查资料------2小时后 mongodb-----配置------不会------查资料------1小时后 然后是各 ...
- Android学习笔记样式资源文件
样式资源和主题资源都是写在styles.xml文件里面的 <style name="title"> <item name="android:textSi ...
- 使用vuex中的store存储数据
Vuex是一个专门为Vue.js应用程序开发的状态管理模式,这个状态自管理应用包括三个模式 state 驱动应用的数据源 view 以声明方式将state映射到视图 actions 响应在view上的 ...