题目:无重复字符的最长子串java
描述:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。算法
示例:数组
有了题目001的经验,咱们应该不会再使用暴力搜索方式来解此题。若使用暴力搜索,要获得全部的子字符串,须要双重for循环,时间复杂度为O(n<sup>2</sup>),获得的每一个字符串还须要判断它是否包含重复字符,这一操做也须要O(n)的耗时,从而使得总时间复杂度达到O(n<sup>3</sup>)。这是没法接受的,因此咱们应该寻求更好的解题方式。学习
此题有一个特定条件:无重复字符。若是使用哈希表来存储每一个字符,咱们就能够在构建子串时得知它是否包含重复字符。下面,咱们以示例中的输入"abcabcbb"为例,来讲明哈希表是如何在此问题中发挥做用的。3d
首先,咱们建一个空的哈希表,key值是每一个字符,value是字符的下标。每当遇到一个哈希表中不存在的字符,咱们就把它存入表中,因此咱们能够依次存入'a'->'b'->'c'三个字符,哈希表中的数据以下图:code
当咱们要存入第四个字符时,哈希表中已经存在了该字符 'a',也就是说"abca"这个子串中包含了重复字符。如今,咱们能够肯定,以第一个字符 'a' 为起点的最长无重复字符子串就是"abc",且它的长度是 ( 字符 'b' 的下标 - 字符 'a' 的下标 + 1),这个值和哈希表的value正好对应。可是以第二个字符 'b' 为起点的子串有可能比"bca"更长,咱们还须要看下一个字符是否重复,为了保证哈希表中的value值和子串中字符的下标值一致,咱们须要把 'a' 的value更新成 3,也就是后一个 'a' 的下标。以下所示:blog
下一个字符是 'b',和上一步状况一致,咱们确认了以第二个字符 'b' 为起点的最长无重复字符子串是"bca",且它的长度是 ( 字符 'a' 的下标 - 字符 'b' 的下标 + 1),可是以第三个字符 'c' 为起点的子串有可能比"cab"更长。重复这个过程,咱们就能够找到以每一个字符为起点的最长无重复字符子串。图片
除了示例的状况,咱们还要考虑第二种状况,好比把输入换成"abcbcad",一开始的结构是一致的,依然是依次存入'a'->'b'->'c'三个字符。当咱们要存入第四个字符时,哈希表中已经存在了该字符'b',可是 'b' 倒是处于中间的字符,这样一来以第一个字符 'a' 为起点的最长无重复字符子串是"abc",以第二个字符 'b' 为起点的最长无重复字符子串是"bc"。而以第三个字符 'c' 为起点的子串,在当前只包含 'c' 和 'b' 两个字符,也就是说字符 'a' 是多余的,以下所示:资源
能够考虑把 'a' 从表中删除,但更优雅的方式是使用标记,由于无用字符必定在当前被当作起点的字符以前,因此只要标记好这个字符的位置,就能够忽略无用字符的存在,以下所示:字符串
之因此不选择删除字符,是由于没法肯定后续是否还会再次出现这个字符,例如本例中字符 'a' 就会在第6位再次出现,这样咱们以前的删除操做就毫无心义了。
上述过程,咱们只须要对字符串进行一次遍历就能获得结果,时间复杂度仅为O(n),这比暴力搜索好得多。参考代码以下:
public int lengthOfLongestSubstring(String s){ Map<Character,Integer> map = new HashMap<>(); int maxLen = 0; int startIndex = 0; int tempMaxLen = 0; for (int i = 0, len = s.length(); i < len; i++) { if (map.containsKey(s.charAt(i)) && map.get(s.charAt(i)) >= startIndex) { startIndex = map.get(s.charAt(i)) + 1; } map.put(s.charAt(i), i); tempMaxLen = i - startIndex + 1; maxLen = maxLen < tempMaxLen ? tempMaxLen : maxLen; } return maxLen; }
以上思路也被称做滑动窗口法,这个比喻还挺形象,但愿你们能记住这个思路,当遇到此类问题时可以多往这方面想想,极大可能想到比暴力搜索好得多的算法。
题目:寻找两个有序数组的中位数
描述:给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,而且要求算法的时间复杂度为 O(log(m + n))。你能够假设 nums1 和 nums2 不会同时为空。
示例 1:
示例 2:
相关源码请加QQ获取。
【感谢您能看完,若是可以帮到您,麻烦点个赞~】
更多经验技术欢迎前来共同窗习交流: 一点课堂-为梦想而奋斗的在线学习平台 http://www.yidiankt.com/
![关注公众号,回复“1”免费领取-【java核心知识点】]
QQ讨论群:616683098
QQ:3184402434
想要深刻学习的同窗们能够加我QQ一块儿学习讨论~还有全套资源分享,经验探讨,等你哦!