LeetCode刷题笔记 3

题目:
给定一个字符串,找出最长的没有重复字符的子字符串的长度。
在这里插入图片描述
我的答案:(Java)
整体思路:
建立哈希表,依次遍历字符串中的字符,哈希表中有则去掉对应位及之前的键值,没有则按续加入哈希表。
第一次提交

import java.util.*;
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Hashtable<Character,Integer> map = new Hashtable<>();
        int i,j,k,flag=0,max=0;
        for (i = 0; i < s.length(); i++) {
            if(map.containsKey(s.charAt(i))){
                k = map.get(s.charAt(i));
                for(j = flag;j <= k;j++){
                    map.remove(s.charAt(j)); 
                }
                if((i-flag)>max)
                {
                    max = i-flag;
                }                
                flag = k+1;
                map.put(s.charAt(i), i);
            }
            else{
                map.put(s.charAt(i), i); 
            }
        }
        return max;
    }
}

报错
在这里插入图片描述
计算最大字符串长度时逻辑有问题。

第二次提交

import java.util.*;
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Hashtable<Character,Integer> map = new Hashtable<>();
        int i,j,k,flag=0,max=0,max_flag=0;
        for (i = 0; i < s.length(); i++) {
        	//如果表中含有此键值,则删掉该位及之前的键值,将新的键值加入到哈希表中
            if(map.containsKey(s.charAt(i))){
                k = map.get(s.charAt(i));
                for(j = flag;j <= k;j++){
                    map.remove(s.charAt(j));
                    max = max-1;
                }               
                flag = k+1;
                map.put(s.charAt(i), i);
                max = max+1;
            }
            else{
                map.put(s.charAt(i), i);
                max = max+1;
            }
            if(max > max_flag)
                max_flag = max;
        }
        return max_flag;
    }
}

成功

答案:
方法一:遍历所有子字符串,在没有重复字符的字符串里寻找最大长度。
时间复杂度O(n3)
方法二:采用开始和结束索引定义滑动窗口

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
    }
}

时间复杂度O(2n) = O(n)
空间复杂度O(min(m,n))

答案三:滑动窗口优化,不是令i一点一点增大,而是直接跳到重复点的位置。(和我的思路大致相同,只不过我在计算最大长度时采用了计算最终长度的方法,方法略显啰嗦)

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;
    }
}

时间复杂度O(n)
空间复杂度O(min(m,n))

需要注意的地方:

  1. 哈希表及字符串相关方法要抄对(如.containsKey())
  2. 滑动窗口的思想

猜你喜欢

转载自blog.csdn.net/qq_34623223/article/details/84349681