LeetCode刷题day002 (Jieky)

LeetCode第3题

/*
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.
*/
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.lang.Math;
public class LongestSubstringWithoutRepeatingCharacters{
     
	// 暴力破解
	public int getSubStringLength01(String s){
     
		int ans = 0;
		for (int i = 0;i < s.length();i++){
     
			for (int j = i+1;j <= s.length();j++){
     
				// 左闭右开,j下标小于s.length
				if (isUnique(s,i,j)){
     
					ans = Math.max(ans,j-i);
				}
			}
		}
		return ans;
	}
	
	public boolean isUnique(String s,int start,int end){
     
		Set<Character> set = new HashSet<>();
		// 左闭右开
		for (int i = start;i < end;i++){
     
			// 一旦发现重复字符串就返回false
			if (set.contains(s.charAt(i))){
     return false;}
			set.add(s.charAt(i));
		}
		// 没有重复子串就返回true
		return true;
	}
	
	// 如果先前的子串有重复字符串,后面的所有子串都不符合要求。
	// 如果先前的子串符合要求,那么不需要重复检验符合要求的部分,
	// 只要检查新的字符串是否在先前的子串中,
	// 若不在就加入当前字符串,
	// 若在则说明以当前开头字符的所有子串都不符合要求,不会更长
	// 删除这个开头字符串。
	public int getSubStringLength02(String s){
     
		Set<Character> set = new HashSet<>();
		// i,j的起始位置相同
		int ans = 0,j = 0,i = 0;
		while (j < s.length() && i < s.length()){
     
			// 空串也是串,判断移动指针是否包含在子串中
			if (set.contains(s.charAt(j))){
     
				// 删除这个开头字符串,这类子串没有增长空间
				set.remove(s.charAt(i++));
				// 注意这里的j没有移动,其和新的子串进行匹配判断
			}else{
     
				// 子串继续增长
				set.add(s.charAt(j));
				// 子串增长后,判断是否超远最长串
				ans = Math.max(ans,j - i + 1);
				// 指向下一个判断的字符
				j++;
			}
		}
		return ans;
	}
	
	// 02版本基于没有增长空间的开头字符串与即将加入的字符串相同,
	// 若是非开头字符串与即将加入的字符相同,则会存在重复判断的问题。
	// 当前的方案是将i一次性移动到重复的字符串之前
	public int getSubStringLength03(String s){
     
		int ans = 0;
		Map<Character, Integer> map = new HashMap<>();
		// j用于持续向前位移
		for (int j = 0, i = 0; j < s.length(); j++) {
     
			if (map.containsKey(s.charAt(j))) {
     
				// map会保存不在当前子串中的字符串下标+1。
				// 当加入的字符串与不在子串中的字符相等时,
				// 保持i不变(i保存子串开头的位置),
				// 否则直接从重复字符的下一位开始寻找更长的子串。
				i = Math.max(map.get(s.charAt(j)), i);
			}
			// 到了这一步,表示j位置的字符可以计入子串的长度
			ans = Math.max(ans, j - i + 1);
			// map存的下标都比实际的大一,是为后期i的跳跃做准备。
			// put操作会将已存在的字符对应的下标保存为最近的下标。
			map.put(s.charAt(j), j + 1);
		}
		return ans;
	}
	
	public static void main(String[] args){
     
		String str1 = "abcabcbb";
		String str2 = "bbbbb";
		String str3 = "pwwkew";
		String str4 = "abcdcca";
		
		LongestSubstringWithoutRepeatingCharacters ins = new LongestSubstringWithoutRepeatingCharacters();
		
		int result = ins.getSubStringLength03(str4);
		System.out.println(result);
	}
}

你可能感兴趣的:(LeetCode,leetcode,java)