[LeetCode] Longest Substring Without Repeating Characters (LinkedHashSet的妙用)
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without
repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
涉及longest substring的题目一般都有着明显的DP特征。这题的一种一维DP思路是:将全部不反复的子字符串按结尾的数组下标分类,让maxEndsWith[i]表示字符串的结尾以i为数组下标,并取最长长度。
对于一个给定的不存在反复字符的字符串。以及一个试图在尾部新添的字符:
1)假设新添字符并不跟所给字符串里的字符反复,那么最长长度加1,即maxEndsWith[i] = maxEnds[i - 1] + 1。
2)假设新加入反复,那么加入此字符的代价是要删除之前的反复字符。以及不计数该反复字符之前的字符。
这样的思路事实上看起来有些类似于数据流算法,核心是维护一个sliding window,保证这个window里全部元素都不反复。涉及去重操作。使用set是最好只是啦。只是这里的难度在于发现反复字符后。不光删除改反复字符,还要删除在此之前的全部字符。
对于满足删除操作,能够用一种非常"别扭"的实现方式。即不用set而改用map,key存字符。value存index。然后另外把map里涵盖的全部index存在一个queue(或者说deque)里。
这样一来。插入和删除都同一时候须要改动map和queue。
事实上对于这样的DP,还能够有一种更简洁优雅的实现方式,就是利用LinkedHashSet这个数据结构。
不同于HashSet。LinkedHashSet会依据元素插入的顺序,把各个元素串联起来成一个链表,所以在遍历的时候会严格遵循插入顺序。由此观之,使用LinkedHashSet的优点非常明显。因为我们这里维护的是一个sliding
window,在反复字符位置之前的字符肯定都是在之前插入window的,插入顺序和遍历顺序都排在反复字符的前面。因此,一旦遇到反复字符。就能够从sliding
window的开头開始删除,一直按遍历顺序删到反复字符出现。并一起删掉。
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0)
return 0; int ret = 1;
Set<Character> set = new LinkedHashSet<Character>();
int[] maxEndsWith = new int[s.length()];
maxEndsWith[0] = 1;
set.add(s.charAt(0));
for (int i = 1; i < s.length(); ++i) {
char c = s.charAt(i);
if (!set.contains(c)) {
set.add(c);
maxEndsWith[i] = maxEndsWith[i - 1] + 1;
} else {
Iterator<Character> it = set.iterator();
while (it.hasNext()) {
char front = it.next();
it.remove(); if (front == c) {
break;
}
}
set.add(c);
maxEndsWith[i] = set.size();
}
ret = Math.max(maxEndsWith[i], ret);
}
return ret;
}
遍历顺序删到反复字符出现。并一起删掉。
注意以上代码尽管有2层循环。可是均摊的时间复杂度还是O(N)。由于每一个字符都只会被增加的window一次。而且只会从window中删除一次。另外这里对数据总共就唯独一次扫描。典型的数据流算法特点。
[LeetCode] Longest Substring Without Repeating Characters (LinkedHashSet的妙用)的更多相关文章
- [LeetCode] Longest Substring Without Repeating Characters 最长无重复子串
Given a string, find the length of the longest substring without repeating characters. For example, ...
- leetcode: longest substring without repeating characters
July 16, 2015 Problem statement: Longest Substring Without Repeating Characters Read the blog: http: ...
- [LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串
Given a string, find the length of the longest substring without repeating characters. Example 1: In ...
- C++ leetcode Longest Substring Without Repeating Characters
要开学了,不开森.键盘声音有点大,担心会吵到舍友.今年要当个可爱的技术宅呀~ 题目:Given a string, find the length of the longest substring w ...
- [LeetCode]Longest Substring Without Repeating Characters题解
Longest Substring Without Repeating Characters: Given a string, find the length of the longest subst ...
- [LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++实现java实现
最长无重复字符的子串 Given a string, find the length of the longest substring without repeating characters. Ex ...
- LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)
题目链接 Given a string, find the length of the longest substring without repeating characters. For exam ...
- LeetCode——Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. For example, ...
- [Leetcode] Longest Substring Without Repeating Characters (C++)
题目: Given a string, find the length of the longest substring without repeating characters. For examp ...
随机推荐
- R与数据分析旧笔记(四)画地图练习
> library(maps) > library(geosphere) 载入需要的程辑包:sp > map("state")#画美国地图 > map(&q ...
- JavaScriptの例
Dateのオブジェクト: <html> <head> <title>Date Object Example</title> </head> ...
- bzoj 1303: [CQOI2009]中位数图
题目链接 给n个数,一个值b, 统计所有以b为中位数的序列的个数.序列长度为奇数.数字在1-n之间, 每个数只出现一次. 如果一个数大于b, 那么将他赋值为1, 小于b赋值为-1, 记录数组中b出现的 ...
- eclipse更改主题
长期使用eclipse,导致视觉疲劳,就想着能否换个主题调节调节. 通过设置window>preferences>appearance设置theme,貌似不起作用. 一查,发现一个绝佳的网 ...
- MYSQL alter procedure alter function 它们只可以更改过程的特性,不可以更改过程的逻辑。
例子: delimiter // create procedure proc_a(in numberA int) 这样create procedure 是正确的 begin select number ...
- phome_enewsclass 数据表字段解释(栏目主表)
字段名 类型 解释 附加说明 classid smallint(6) 栏目ID bclassid smallint(6) 父栏目ID classname varchar(50) 栏目名称 ...
- 如何使用Excel和Word编辑和打印条形码
本文介绍如何使用Microsoft Office Excel 2007和Microsoft Office Word 2007进行条形码的编辑后,通过普通的办公打印机将条形码打印出来. 对于少量,简单的 ...
- swig include使用方法
{% block content2 %} {% include "footer.html" %} {% endblock %} include语句必须放到 block模块中,不然不 ...
- S3C6410 GPIO操作接口
在后面的驱动学习中,需要对GPIO进行一系列的操作,了解这些引脚操作有助于编码的效率. 一.配置GPIO S3C6410要使用其引脚时,需要对其进行配置,如配置为输入/输出/中断等功能,根据芯片手册来 ...
- Yii2简单纪要
网上经常拿Yii来类比ROR,从MVC角度,使用体验及代码风格上确实有很多相似的地方.不过看配置文件发现Yii2不止是受rails的影响,同样有不少spring的影子,最明显的就是配置文件中很多IOC ...