leetcode
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
方法一:采用双指针加哈希表,滑动窗口思想。
即左右指针left,right。从前往后遍历字符串。righ自增,同时哈希表维护记录[left,righ]中字符的下标。遇到重复字符,就更新左指针left的位置,保证[left,right]中不出现重复字符。每次遍历都更新最长字串的长度。
时间复杂度:只遍历了一遍字符串,复杂度为O(N)
class Solution { public int lengthOfLongestSubstring(String s) { int n = s.length(); int left = 0; int right = 0; int ans = 0; HashMap<Character, Integer> map = new HashMap<>(); while (right < n) { char c = s.charAt(right); //重复字符,直接更新左指针位置 if (map.containsKey(c)) { left = Math.max(left, map.get(c) + 1); } map.put(c, right); ans = Math.max(ans, right - left + 1); right++; } return ans; } }
方法二:双指针加数组,还是滑动窗口
思路与方法一一样,就是采用数组代替我们哈希表。因为leetcode上说字符串s 由英文字母、数字、符号和空格组成,根据ASCLL码,那么我们可以开一个128长度的数组。以字符为下标,以字符在原字符串的下标为数组的值。
class Solution { public int lengthOfLongestSubstring(String s) { int n = s.length(); int left = 0; int right = 0; int ans = 0; int[] ch = new int[128]; Arrays.fill(ch, -1); while (right < n) { char c = s.charAt(right); if (ch[c] != - 1) { left = Math.max(left, ch[c] + 1); } ch[c] = right; ans = Math.max(ans, right - left + 1); right++; } return ans; } }
时间复杂度:同样为O(N),但是数组会快一点。