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的妙用)的更多相关文章

  1. [LeetCode] Longest Substring Without Repeating Characters 最长无重复子串

    Given a string, find the length of the longest substring without repeating characters. For example, ...

  2. leetcode: longest substring without repeating characters

    July 16, 2015 Problem statement: Longest Substring Without Repeating Characters Read the blog: http: ...

  3. [LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串

    Given a string, find the length of the longest substring without repeating characters. Example 1: In ...

  4. C++ leetcode Longest Substring Without Repeating Characters

    要开学了,不开森.键盘声音有点大,担心会吵到舍友.今年要当个可爱的技术宅呀~ 题目:Given a string, find the length of the longest substring w ...

  5. [LeetCode]Longest Substring Without Repeating Characters题解

    Longest Substring Without Repeating Characters: Given a string, find the length of the longest subst ...

  6. [LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++实现java实现

    最长无重复字符的子串 Given a string, find the length of the longest substring without repeating characters. Ex ...

  7. LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)

    题目链接 Given a string, find the length of the longest substring without repeating characters. For exam ...

  8. LeetCode——Longest Substring Without Repeating Characters

    Given a string, find the length of the longest substring without repeating characters. For example, ...

  9. [Leetcode] Longest Substring Without Repeating Characters (C++)

    题目: Given a string, find the length of the longest substring without repeating characters. For examp ...

随机推荐

  1. spring 入门篇

    spring 入门篇         相对于Hibernate(冬眠),Spring(春天),具有更多的诗意与希望的感觉,是为了解决传统J2EE开发效率过低.开发商之间不统一.没有真正实现“写一次到处 ...

  2. 使用Integer类实现二叉树排序

    class BinaryTree {     class Node {         private Comparable data;         private Node left;      ...

  3. CSS3里面的高级属性

    -webkit-tap-highlight-color 这个属性只用于iOS (iPhone和iPad).当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就会出现一个半透明的灰色 ...

  4. [暂停一天]从零开始PHP学习 - 第六天

    今天这个系列没有时间去写了 在公司完善一个项目     已经备好6瓶咖啡 两天 + 一夜 完成这个项目  真是苦逼 诶 反正这几天 明白一个道理:别以为你多牛B 你不会的东西多了!  比你牛B的人也多 ...

  5. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  6. 史上最简单的Hibernate入门简单介绍

    事实上Hibernate本身是个独立的框架,它不须要不论什么web server或application server的支持.然而,大多数的Hibernate入门介绍都加入了非常多非Hibernate ...

  7. AngularJS Directive 学习笔记

    指令 Directive 指令要点 大漠老师的教学节点 解析最简单的指令 hello: 匹配模式 restrict 解析最简单的指令 hello: template.tempmlateUrl.$tem ...

  8. UVA1471( LIS变形)

    这是LIS的变形,题意是求一个序列中去掉某个连续的序列后,能得到的最长连续递增序列的长度. 用DP的解法是:吧这个序列用数组a来记录,再分别用两个数组f记录以i结尾的最长连续递增序列的长度,g[i]记 ...

  9. QT中QWidget、QDialog及QMainWindow的区别

    本文转自http://www.cnblogs.com/aqxin/archive/2011/05/23/2054156.html QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基 ...

  10. POJ 3630 Phone List(trie树的简单应用)

    题目链接:http://poj.org/problem?id=3630 题意:给你多个字符串,如果其中任意两个字符串满足一个是另一个的前缀,那么输出NO,否则输出YES 思路:简单的trie树应用,插 ...