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

示例 1:

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

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

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

动态规划解

dp[i]:到以第i个字符结尾的不包含重复字符的最大长度
对于第i个字符:
1、第i个字符从未出现过,dp[i]=dp[i-1]+1
2、第i个字符出现过:找到第i个字符最近一次出现的位置index(从第i个往前找),记两个距离为d=i-index
【a】、d<= dp[i-1],即这个字符出现在以第i-1个字符结尾的不含重复字符的字符串中,则dp[i]=d,表示从第最近一次出现后重新计算长度:
例如:
i: 0 1 2 3 4 5
s: 1 2 3 4 5 4
dp: 1 2 3 4 5 2
最后的这个2 = 5 - 3(最近一次出现的i);
【b】、d>dp[i-1],即这个字符没有出现在以第i-1字符结尾的不含重复的最大长度字符串中。
dp[i] = dp[i-1] +1;
例如:
i: 0 1 2 3 4 5 6
s: 1 2 3 4 5 4 1
dp: 1 2 3 4 5 2 3
s最后的这个1虽然在i=0的位置出现过,但是由于d=6-0=6>dp[5],所以dp[6]=dp[5]+1,也就是说我们的子串已经重新更新了。

class Solution {public:int lengthOfLongestSubstring(string s) {unordered_set<char> myset;int sz = s.size();int ans = 1;if (sz == 0) return 0;vector<int> dp(sz, 0);dp[0] = 1;for (int i = 0;i < sz;i++)       //起点{//如果第i个字符出现过if (myset.find(s[i]) != myset.end()){if (i >= 1){int index = get_index(s, s[i],i);     if (index == -1) index = 0;int d = i - index;if (d <= dp[i - 1]) dp[i] = d;else dp[i] = dp[i - 1] + 1;}}//如果没有出现过,记录下来else{myset.insert(s[i]);if (i >= 1){dp[i] = dp[i - 1] + 1;}}ans = max(ans, dp[i]);}return ans;}int get_index(string s, char x,int start) {int sz = s.size();if (sz == 0) return -1;for (int i = start-1;i >=0 ;i--){if (s[i] == x) return i;}return -1;       //没有找到}
};


参考https://zhuanlan.zhihu.com/p/112545613进行优化;

f[i]:以原字符串s中,以位置i的字符s[i]为右边界时的最优左边界
例如样例 a b c a b c b b
对应的f数组为:
f[0] = 0,左边界为第一个a,对应子串为a
f[1] = 0,左边界为第一个a,对应子串为ab
f[2] = 0,左边界为第一个a,对应子串为abc
f[3] = 1,左边界为第一个b,对应子串为bca
f[4] = 2,左边界为第一个c,对应子串为cab
f[5] = 3,左边界为第二个a,对应子串为abc
f[6] = 5,左边界为第二个c,对应子串为cb
f[7] = 7,左边界为最后一个b,对应子串为b
f[0] = 0;
对于f[i],只需要考察f[i-1]到i-1这个区间中是否出现过s[i]
如果没有出现过,则f[i]=f[i-1]
如果出现过,那么必然只出现了一次,因为f[i-1]到i-1这个区间中必然不存在重复字符,于是设s[i]出现的位置为pos,则f[i]=pos+1;在重复的字符后面的一个字符作为新的起始点。
可以发现,左边界的更新是单调递增的,因此s中每个字符最多也只会遍历一遍,时间复杂度为O(n)。
由于f[i]的更新只与f[i-1]有关,因此不需要维护整个数组。

class Solution(object):def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""left = 0res = 0for right,char in enumerate(s):pos = s.find(char,left,right)if pos >=0:left = pos+1else: left = leftres = max(res,right-left+1) return res

滑动窗口解

其实和dp第一种方法类似:
滑动窗口的核心思路如下:
比如输入字符串为:abcdecfg,字串 abcde 满足题目要求,当新加入 c 时,字串变成了 abcde c,字符 c 重复了,不满足要求。这时候,只需要将第一个重复的字符 c 连同之前的字符丢掉,变成 de c,就又能满足要求了。每新加一个字符,都更新最长字串的长度,遍历完一遍之后,即可得到答案。
问题在于如何丢掉第一个重复字符连同之前的字符,其实我们不用真的丢掉,而是可以维护一个左边界值 left ,有重复字符的话,就把 left 更新为重复字符的下一个位置,假装丢掉了它和之前的字符。
参考链接:https://blog.csdn.net/m0_37433111/article/details/108743399

class Solution {public:int lengthOfLongestSubstring(string s) {int sz = s.size();if (sz == 0) return 0;int left=0;int maxlen=1;// val存放字符在原字符串的索引unordered_map<char,int> u_map;for (int i = 0;i < sz;i++)       //起点{//如果有重复的字符,左边界更新到重复的字符后面一个if(u_map.find(s[i])!=u_map.end()) left = max(left,u_map[s[i]]+1);//如果没有重复的字符,左边界保持不变也就是left=left,可以省略不写//将s[i]插入、u_map[s[i]] = i;     //如果有重复的,则将坐标更新为靠后的坐标// 更新最长子串的长度maxlen = max(maxlen,i-left+1);}return maxlen;}
};

LeetCode 3:无重复字符的最长子串 思考分析相关推荐

  1. [贪心|字符串] leetcode 3 无重复字符的最长子串

    [贪心|字符串] leetcode 3 无重复字符的最长子串 1.题目 题目链接 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例1: 输入: "abcabcbb" ...

  2. 【LeetCode】无重复字符的最长子串【滑动窗口法】

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  3. LeetCode 3. 无重复字符的最长子串(滑动窗口+哈希)

    1. 题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 " ...

  4. [leetcode] 3.无重复字符的最长子串

    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 " ...

  5. LeetCode之无重复字符的最长子串

    1. 题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度.示例 1:输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "ab ...

  6. leetcode算法—无重复字符的最长子串 Longest Substring Without Repeating Characters

    关注微信公众号:CodingTechWork,一起学习进步. 题目 Longest Substring Without Repeating Characters: Given a string, fi ...

  7. LeetCode 3. 无重复字符的最长子串 (滑动窗口哈希表)

    3. 无重复字符的最长子串 题意: 找子串 子串中无重复字符 要求子串长度最长 解法1(暴力法) 思路: 建立一个长度不断变小的滑动窗口 用一个指针指针扫描窗口内的每个元素: 如果除去指针指向的那个元 ...

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

    内容描述:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. class Solution(object):def lengthOfLongestSubstring(self, s):& ...

  9. LeetCode 3. 无重复字符的最长子串(Longest Substring Without Repeating Characters)

    题目描述 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. ...

最新文章

  1. 中介分析 相对直接效应 相对简介效应_中介效应分析方法和流程
  2. leetcode算法题--地图中的最高点
  3. Oracle_sql优化基础——优化器总结
  4. 有趣的linux指令
  5. elasticsearch in查询_Python Elasticsearch DSL 查询、过滤、聚合操作实例
  6. if __name__ == __main__:什么意思_好冷的Python if __name__==__main__是啥东东
  7. mysql数据修改-DEDE
  8. 你需掌握的CSS知识都在这了(长文建议收藏,文末有福利)
  9. 手把手教你训练一个秒杀科比的投篮AI,不服来练 | 附开源代码
  10. Python基础教程:(小窍门)如何优化Python占用的内存
  11. 数据库SQL语言学习--上机练习3(插入 更新 删除)
  12. java poi设置导出的excel带下拉
  13. Enigma密码机原理图解
  14. 推荐一个免费的JSP空间
  15. ssm基于Android的签到系统APP(ssm+uinapp+Mysql)
  16. 《软件测试》第二章 软件开发的过程
  17. 阿里云物联网平台数据解析(python)
  18. 耿丹计科16-2大家庭
  19. 终身学习 思维导图
  20. LinkedList 类 的简单应用

热门文章

  1. php一句话后门学习(含免杀)
  2. linux 提升cpu权限,CPUlimit有效防止Linux系统CPU过载
  3. 阿里云服务器mysql默认密码_阿里云服务器修改MySQL初始密码---Linux学习笔记
  4. EventUtil.addHandler方法
  5. JS_单个或多个文件上传_不支持单独修改
  6. javascript 分时函数 分批次添加DOM节点 timeChunk
  7. Linux 文件属性
  8. 常用的好用的window工具
  9. Android官方培训课程中文版(v0.9.5)
  10. 小白学数据分析-----留存率分析_I[次日留存率突然下降了50%?]