LeetCode.3:Longest Substring Without Repeating Characters

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

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 
Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 

Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

粗略的第一想法就是,把字符串的所有子串全部试一遍,找没有重复字符的子串;然后取所有子串中满足条件最长的那个。然鹅,这样就超时了!!!!,悲伤辣么大,代码如下:

public class LongestSubstringWithoutRepeatingCharacters {

	public static void main(String[] args) {
		
		String string="ab";
		
		System.out.println(lengthOfLongestSubstring(string));
	}
	
	static int lengthOfLongestSubstring(String s) {
		 if (s.length()==0)
	            return 0;
		int maxlen = 1;
		for (int i = 0; i <= s.length(); i++) {
			for (int j = i+1; j <= s.length(); j++) {
				String string=new String(s.substring(i, j));
				if(noReport(string)) {
					maxlen=maxlen>(j-i)? maxlen:(j-i);
				}
			}
		}
		return maxlen ;
	}

	 static boolean noReport(String string) {
		// TODO Auto-generated method stub
		 Set<String> set = new HashSet<>();
		 for (int i = 0; i < string.length(); i++) {
			if (set.contains(string.substring(i, i+1))) {
				return false;
			}
			else {
				set.add(string.substring(i,i+1));
			}
		} 
		return true;
	}
}

后来想了想,一个长度为n的字符串所有的子串个数的时间复杂度是O(n^2 ),再加上对每个子串判断是否有重复,所以整体的时间复杂度应该是O(n^3 ),这个复杂度肯定超时啊。

转换思路,在暴力破解法中,需要反复检查一个子字符串是否含有有重复的字符,但这是没有必要的。如果从索引 i 到 j-1 之间的子字符串 s [ i , j ] 已经被检查为没有重复字符。我们只需要检查 s[j+1]对应的字符是否已经存在于子字符串 s [ i , j ] ​​ 中。
如果 j 对应的字符没出现过,则追加到当前寻找的字符串上;
如果 j 对应的字符在集合中出现过,那么就移动 i,同时在集合中把索引 i 对应的字符逐个删去,直到集合中 j 对应的字符没出现过。

package com.RyanWang;

import java.util.HashSet;
import java.util.Set;

import javax.print.DocFlavor.CHAR_ARRAY;

public class LongestSubstringWithoutRepeatingCharacters {

	public static void main(String[] args) {
		
		String string="abcabcbb";
		
		System.out.println(lengthOfLongestSubstring(string));
	}
	

	static int lengthOfLongestSubstring(String s) {
		 if (s.length()==0)
			 return 0;
		 int maxlen = 1,i=0,j=0;
		 Set<String> set = new HashSet<>();
		 while(i<s.length()&&j < s.length())  {
			 
			if (!set.contains(s.substring(j, j+1))) {
				set.add(s.substring(j, j+1));
				j++;
				maxlen=maxlen>(j-i)? maxlen:(j-i);
				
			}
			else {
				set.remove(s.substring(i,i+1));
				i++;
			}
		}
		 
		 return maxlen;
	}
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值