LeetCode 3:Longest Substring Without Repeating Characters

LeetCode 3:Longest Substring Without Repeating Characters

题目描述:Longest Substring Without Repeating Characters

对字符串和数组问题可以采用滑动窗口的方法

解题过程

看到这题时,想到了kmp算法。
直接对s进行扫描,当没有重复时,记录到字符串中,并声明max记录最长子串的长度,用以判断。如果,遇到重复的字符时,则判断该子串是否为当前最长子串;并将指针移动到与之重复的字符之后,减少循环次数。

    public int lengthOfLongestSubstring(String s) {
        if (s.length()==0||s.length()==1) {
			return s.length();
		}
		int k=0;
		int max=0;
		String ssString="";
		while(k<s.length()) {
			ssString+=s.charAt(k);
			int j=k+1;
			for(;j<s.length();j++) {
				if (ssString.indexOf(s.charAt(j))==-1) {
					ssString+=s.charAt(j);
				}
				else {
					k=s.indexOf(s.charAt(j),k)+1;
					
					break;
				}
			}
			if (max<ssString.length()) {
				max=ssString.length();
			}
			ssString="";
			if (max>=s.length()-k||j==s.length()-1) {
				break;
			}
		}
		return max;
    }

题解:

滑动窗口
滑动窗口是数组/字符串问题中常用的抽象概念。 窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合。

使用 HashSet 作为滑动窗口, 将字符存储在当前窗口 [i, j)最初 j = i)中。 然后我们向右侧滑动索引 j,如果它不在 HashSet 中,也就是当前窗口没有重复字符时,继续滑动 ,也就是j++。直到 s[j] 已经存在于 HashSet 中,出现了重复字符。此时,找到的没有重复字符的最长子字符串将会以索引 i 开头。如果对所有的 i这样做,就可以得到答案。

但是,还可以继续进行优化,定义字符到索引的映射,使用HashMap。如果找到重复的字符时,就可以立即跳过该窗口。
也就是说,如果 s[j]在 [i, j) 范围内有与 j’重复的字符,则不需要逐渐增加 i 。 可以直接跳过 [i,j’]范围内的所有元素,并将 i 变为 j’ + 1。

    public int lengthOfLongestSubstring(String s) {
		int max=0;
		Map<Character, Integer> map=new HashMap<Character, Integer>();
		for(int j=0,i=0;j<s.length();j++) {
			if (map.containsKey(s.charAt(j))) {
				i=Math.max(map.get(s.charAt(j)), i);
			}
			max=Math.max(j-i+1, max);
			map.put(s.charAt(j), j+1);
		}
		return max;
	}

时间复杂度:O(n),索引 j 将会迭代 n 次。
空间复杂度(HashMap):O(min(m, n))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值