Leetcode刷题3. 无重复字符的最长子串

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

示例 1:

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

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

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

输入: s = ""
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

感谢BugTime怎么用滑动窗口&为何用滑动窗口数据结构和算法带图文分析的6种解法

class Solution {
    public int lengthOfLongestSubstring(String s) {
//		return lengthOfLongestSubstringI(s);
		return lengthOfLongestSubstringII(s);
	}

	//方法二:滑动窗口
	//定义hashset记录窗口中的字符,使用两个指针start和end,移动end指针扩大窗口,直到遇到重复的字符
	//遇到重复字符时,从hashset中移除start指针指向的字符,并向右移动start指针,直到窗口中没有重复的字符
	//遍历的过程中,更新结果res
	//时间复杂度O(n),空间复杂度O(min(m,n))其中m为ASCII字符集大小
	private int lengthOfLongestSubstringII(String s) {
		if (s == null || s.length() == 0) {
			return 0;
		}
		Set<Character> set = new HashSet<>();
		int start = 0;
		int maxLen = 0;
		for (int end = 0; end < s.length(); end++) {
			char c = s.charAt(end);
			while (set.contains(c)) {
				set.remove(s.charAt(start));
				start++;
			}
			set.add(c);
			maxLen = Math.max(maxLen, end - start + 1);
		}
		return maxLen;
	}

	//方法一:滑动窗口
	//初始化window[]整型数组,它的大小为256,对应于扩展ASCII码范围内的所有可能字符。这个数组用于跟踪当前子串中每个字符出现的次数。
	//定义left和right,表示滑动窗口的左右边界。
	//遍历字符串,统计字符出现的次数。当某个字符出现次数大于1时,这时需要缩小窗口来排除重复。通过持续增加left的值,并减少window中字符出现的字数,直到window中当前考察的字符计数不再大于1.
	//每次当窗口扩大或缩小后,更新结果res
	//时间复杂度O(n),空间复杂度O(1)
	private int lengthOfLongestSubstringI(String s) {
		if (s == null || s.length() == 0) {
			return 0;
		}
		int[] window = new int[256];
		int left = 0;
		int right = 0;
		int maxLen = 0;
		while (right < s.length()) {
			char c = s.charAt(right);
			window[c]++;
			right++;

			while (window[c] > 1) {
				char d = s.charAt(left);
				//缩小窗口的左边界
				left++;
				//减少d的计数,因为d已经不再是窗口的一部分
				window[d]--;
			}
			maxLen = Math.max(maxLen, right - left);
		}
		return maxLen;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值