定义
变位词是指组成各个单词的字母及每个字母出现的次数完全相同,只是字母排列的顺序不同。如“pots”、“stop”和“tops”
特点
2022/10/27
给定两个字符串
s1
和s2
,写一个函数来判断s2
是否包含s1
的某个变位词。换句话说,第一个字符串的排列之一是第二个字符串的 子串 。
思路:s1的字符在s2中全部存在,并且连续(子串),返回true
实现
使用哈希表存储s1中出现的字符及其次数
使用双指针定位一个子字符串,其中一个指针left指向子字符串的第一个字符,另一个指针指向子字符串的最后一个字符
如果子字符串对应的charToCount全为0,那么证明该子字符串为字符串s1的变位词,返回true
代码
class Solution {public boolean checkInclusion(String s1, String s2) {if (s1.length() > s2.length()){return false;}int len1 = s1.length();int[] charToCount = new int[26];for (int i = 0; i < len1; i++){charToCount[s1.charAt(i)-'a']++;charToCount[s2.charAt(i)-'a']--;}if (areAllZeor(charToCount)){return true;}for (int i = len1; i < s2.length(); i++){charToCount[s2.charAt(i-len1)-'a']++;// 删除左指针对应的字符charToCount[s2.charAt(i)-'a']--;// 添加右指针对应的字符if (areAllZeor(charToCount)){return true;}}return false;}public boolean areAllZeor(int[] charToCount){for (int i = 0; i < charToCount.length; i++){if (charToCount[i] != 0){return false;}}return true;}
}
复杂度
2022/10/27
给定两个字符串
s
和p
,找到s
中所有p
的 变位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。变位词 指字母相同,但排列不同的字符串。
思路:逐一判断字符串s中长度为lenP的子字符串是不是字符串p的变位词,如果是则将起始索添加至结果集
实现
代码
class Solution {public boolean checkInclusion(String s1, String s2) {if (s1.length() > s2.length()){return false;}int len1 = s1.length();int[] charToCount = new int[26];for (int i = 0; i < len1; i++){charToCount[s1.charAt(i)-'a']++;charToCount[s2.charAt(i)-'a']--;}if (areAllZeor(charToCount)){return true;}for (int i = len1; i < s2.length(); i++){charToCount[s2.charAt(i-len1)-'a']++;// 删除左指针对应的字符charToCount[s2.charAt(i)-'a']--;// 添加右指针对应的字符if (areAllZeor(charToCount)){return true;}}return false;}public boolean areAllZeor(int[] charToCount){for (int i = 0; i < charToCount.length; i++){if (charToCount[i] != 0){return false;}}return true;}
}
复杂度
给定一个字符串
s
,请你找出其中不含有重复字符的 最长连续子字符串 的长度。
2022/10/27
思路:使用双指针定位一个子字符串,使用哈希表判断子字符串是否存在重复元素,如果有重复元素,当出现重复字符,收缩左边界直到重复字符消失
实现
代码 hashset
class Solution {public int lengthOfLongestSubstring(String s) {Set words = new HashSet<>();int res = 0;int left = 0;int right = 0;while ( left <= right && right < s.length()){if (!words.contains(s.charAt(right))){words.add(s.charAt(right));}else{res = Math.max(res,right - left);while (left < s.length() && s.charAt(left) != s.charAt(right)){words.remove(s.charAt(left));left++;}left++;}right++;}res = Math.max(res,right - left);return res;}
}
代码 boolean数组
class Solution {public int lengthOfLongestSubstring(String s) {boolean[] words = new boolean[256];int res = 0;int left = 0;int right = 0;while ( left <= right && right < s.length()){if (!words[s.charAt(right)]){words[s.charAt(right)] = true;}else{res = Math.max(res,right - left);while (left < s.length() && s.charAt(left) != s.charAt(right)){words[s.charAt(left)] = false;left++;}left++;}right++;}res = Math.max(res,right - left);return res;}
}
给定两个字符串
s
和t
。返回s
中包含t
的所有字符的最短子字符串。如果s
中不存在符合条件的子字符串,则返回空字符串""
。如果
s
中存在多个符合条件的子字符串,返回任意一个。注意: 对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。
[可以包括其他字符的最短’变位词’]
2022/10/29
思路:使用双指针定位s的子字符串,使用哈希表记录出现的字母及次数
实现:
代码
class Solution {public String minWindow(String s, String t) {if (s.length() < t.length()){return "";}int[] charToCounts = new int['z'-'A'+1];int left = 0;int right = 0;int minLeft = 0;// 左闭右闭int minRight = Integer.MAX_VALUE;for (; right < t.length(); right++){charToCounts[t.charAt(right)-'A']++;charToCounts[s.charAt(right)-'A']--;}if (isContainsAll(charToCounts)){minRight = right - 1;}while (right < s.length()){charToCounts[s.charAt(right)-'A']--;// 左边界有重复字符或者不是所需字符 收缩左边界while (left <= right && charToCounts[s.charAt(left)-'A'] < 0){ charToCounts[s.charAt(left)-'A']++;left++;}if (isContainsAll(charToCounts)){// 包含全部字符if (right - left < minRight - minLeft){minRight = right;minLeft = left;}}right++;}return minRight == Integer.MAX_VALUE ? "" : s.substring(minLeft,minRight+1);}public boolean isContainsAll(int[] charToCounts){for(int i = 0; i < charToCounts.length; i++){if (charToCounts[i] > 0){return false;}}return true;}
}
复杂度
You are given a string
word
that consists of digits and lowercase English letters.You will replace every non-digit character with a space. For example,
"a123bc34d8ef34"
will become" 123 34 8 34"
. Notice that you are left with some integers that are separated by at least one space:"123"
,"34"
,"8"
, and"34"
.Return the number of different integers after performing the replacement operations on
word
.Two integers are considered different if their decimal representations without any leading zeros are different.
2022/12/6
思路:使用双指针定位字符串中整数的起始位置和结束位置,去除前导0后,将该整数放入哈希表中,最后返回哈希表的大小即可。
实现
class Solution {public int numDifferentIntegers(String word) {Set set = new HashSet<>();int len = word.length();int l = 0; int r = 0;while (l < len && r < len){// 找到左边界while (l < len && word.charAt(l) >= 'a' && word.charAt(l) <= 'z'){l++;}if (l == len){break;}// 找到右边界r = l;while ( r < len && word.charAt(r) >= '0' && word.charAt(r) <= '9') {r++;}// 去除前导0while (l != r && word.charAt(l) == '0'){l++;}String num = word.substring(l, r);set.add(num);l = r + 1;}return set.size();}
}
复杂度