无重复最长字符子串

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

示例:

给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。

给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。

给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串"pwke" 是 子序列  而不是子串。

暴力解法:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int l = s.length();
		int max = 0;
		for(int i = 0; i < l; i++){
			for(int j = i + 1; j <= l; j++){
				if(AllUnique(s, i, j)) max = Math.max(max, j - i);
			}
		}
		return max;
    }
   public boolean AllUnique(String s, int start, int end){
		Set<Character> set = new HashSet<>();
		for(int i = start; i < end; i++){
			Character ch = s.charAt(i);
			if(set.contains(ch)) return false;
			set.add(ch);
		}
		return true;
	}
}
复杂度分析:

o(n^3)


HashSet的知识点:
HashSet(): 构造一个空的容器,默认容量为16
  1. hashset.add("abc");  
  2. //向hashset中添加一个整数  
  3. hashset.add(1);  
  4. //向hashset中添加一个字符  
  5. hashset.add('a');  
  6. //向hashset中添加一个数组  
  7. int[] abc={10,11,12};  
  8. hashset.add(abc);  
  9. //向hashset中添加一个自定义对象  
  10. Cat cat1=new Cat("asd"2);  
  11. hashset.add(cat1);//向hashset中添加一个对象</span> 

常用方法:

hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false。

删除元素:

hashset.clear():从此 set 中移除所有元素。

hashset.remove(Object o):如果指定元素存在于此 set 中,则将其移除。

hashset.isEmpty():如果此 set 不包含任何元素,则返回 true

hashset.contains(Object o):如果此 set 包含指定元素,则返回 true

hashset.size():返回此 set 中的元素的数量(set 的容量)。

滑动窗口解法:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int l = s.length();
        int max = 0, i = 0, j = 0;
        Set<Character> set = new HashSet<>();
        while(i < l && j < l){
            if(!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                max = Math.max(max, j - i);
            }
            else{
                set.remove(s.charAt(i++));
            }
        }
        return max;
    } 
}

Complexity Analysis

  • Time complexity : O(2n) = O(n)O(2n)=O(n). In the worst case each character will be visited twice by ii and jj.

  • Space complexity : O(min(m, n))O(min(m,n)). Same as the previous approach. We need O(k)O(k) space for the sliding window, where kk is the size of the Set. The size of the Set is upper bounded by the size of the string nnand the size of the charset/alphabet mm.

优化滑动窗口解法:
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>(); // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }
}

现实情况没必要每次都把i一步一步移动,可以将i直接移动至元素重新出现的位置

如此时的窗口的大小为[i, j),如果是s[j]和窗口中的某个元素重复,此时的索引值为j',我们可以直接跳过[i, j']
将此时的窗口大小调整为[j'+1, j)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值