• Leetcode 3. 无重复字符的最长子串 做题小结


    题目:

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

    示例 1:

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

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

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

    思路:

    滑动窗口法:

    思路和算法

    我们先用一个例子来想一想如何在较优的时间复杂度内通过本题。

    我们不妨以示例一中的字符串 exttt{abcabcbb}abcabcbb 为例,找出 从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案。对于示例一中的字符串,我们列举出这些结果,其中括号中表示选中的字符以及最长的字符串:
    在这里插入图片描述

    在这里插入图片描述
    判断重复字符

    在上面的流程中,我们还需要使用一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

    至此,我们就完美解决了本题。

    代码如下:

    public int lengthOfLongestSubstring(String s) {
    		 
    		int ans = 0;
    		int rk=0;
    		HashSet<Character> occ = new HashSet<Character>();
    		for(int i=0;i<s.length();i++) {
    			if(i!=0) {
    				occ.remove(s.charAt(i-1));
    			}
    			while(rk<s.length() && !occ.contains(s.charAt(rk))) {
    				occ.add(s.charAt(rk));
    				rk++;				
    			}
    			ans = Math.max(ans, rk-i);	
    		}
    		System.out.println(ans);
    		return ans;
    	}
    

    知识点小结:

    这里使用了HashSet创建了character的数组,先让我们了解一下HashSet
    HashSet是基于HashMap来实现的,
    是一个不允许有重复元素的集合,但是HashSet允许有空值。另外HashSet是无序的,
    即不会记录插入的顺序。在线程安全方面,它也不是线程安全的,
    如果多个线程尝试同时修改HashSet,则最终的结果是不正确的。
    在多线程访问时,必须显式同步对HashSet的并发访问。
    
    一个原因是HashSet创建的数组有remove方法,移除的是元素,不是下标。
    而使用ArrayList无法使用remove直接移除数组的元素
    
  • 相关阅读:
    JAVA多线程(七) ReentrantLock原理分析
    JAVA多线程(六) synchronize原理分析
    JAVA多线程(五) volatile原理分析
    pandas
    从美国总经理,到三一重卡的董事长,梁林河的重卡梦
    【转载】低水平领导的十大表现
    kill及其衍生程序
    python -m venv 的使用
    Python多版本启动器
    Pyinstaller最流行的打包程序
  • 原文地址:https://www.cnblogs.com/nmydt/p/14256401.html
Copyright © 2020-2023  润新知