给你一个由小写字母组成的长度为n的字符串 S ,找出所有长度为 k 且包含重复字符的子串,请你返回全部满足要求的子串的数目。
数据范围: ,
进阶: 时间复杂度,空间复杂度
把字符串看成一条长为n的线,一个长为k的毛毛虫从线上爬过去,初始位置为[0,k-1] 用双循环检查毛毛虫内部有没有重复的字母,有就跳过双循环,答案+1 毛毛虫向前爬一步(left+1和right+1) 直到爬到终点(right == n) int numKLenSubstrRepeats(string s, int k) { int left = 0,right = k-1; int ans = 0; int n = s.size(); bool YN = false; while(right != n) { for(int i=left;i<=right;i++) { for(int j=i+1;j<=right;j++) { if(s[i] == s[j]) { ans++; YN=true; break; } } if(YN) { YN = false; break; } } left++; right++; } return ans; }
class Solution: def numKLenSubstrRepeats(self , s , k ): # write code here num = 0 for i in range(len(s)-k+1): if len(set(s[i:i+k])) < k: num += 1 return num
public int numKLenSubstrRepeats (String s, int k) { // write code here int n = s.length(); int res = 0; Set<Character> set = new HashSet<>(); for(int i = k-1; i < n; i++){ for(int j = 0; j < k; j++){ set.add(s.charAt(i-j)); } if(set.size() < k){ res++; } set.clear(); } return res; }
int numKLenSubstrRepeats(string s, int k) { // T(n) = O(n), S(n) = O(n) if (k == 0) { return 0; } int l = 0; int repeated = 0; int n = s.size(); unordered_map<char, int> mp; int ret = 0; for (int r = 0; r < n; ++r) { mp[s[r]]++; if (mp[s[r]] == 2) { ++repeated; } if (k > 0) { --k; } else { mp[s[l]]--; if (mp[s[l]] == 1) { --repeated; } ++l; } if (k == 0 && repeated > 0) { ++ret; } } return ret; }
public class NumKLenSubstrRepeats { public int numKLenSubstrRepeats(String s, int k) { // write code here // 问题一:如何判断最后一串数字 Set<Character> set = new HashSet<>(); char[] chars = s.toCharArray(); int count = 0; for (int i = 0; i <= chars.length - k; i++) { set.add(chars[i]); for (int j = i + 1; j < i + k; j++) { if (!set.contains(chars[j])) { set.add(chars[j]); continue; } else { count++; break; } } set.clear(); } return count; } }
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ unordered_map<char, int> hash; bool check() { // 判断是否有出现两次的字符 for(auto iter = hash.begin(); iter != hash.end(); iter++) { if(iter->second > 1) return true; } return false; } int numKLenSubstrRepeats(string s, int k) { // write code here int len = s.length(); int left = 0, right = 0; int res = 0; while(right < len) { // 记录出现过的字符次数 hash[s[right]]++; // 间隔为给定的大小时 查询是否出现两次 if(right-left >= k-1) { // 判断是否有出现两次的字符 if(check()) res++; // 指针右移 对应出现的字符次数减一 hash[s[left++]]--; } right++; } return res; } };
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ public int numKLenSubstrRepeats (String s, int k) { // write code here HashMap<Character, Integer> map = new HashMap<>(); int right = 0; int left = 0; int res = 0; while(right < s.length()) { int times = map.getOrDefault(s.charAt(right), 0); if(right - left + 1 > k || times > 0) { map.put(s.charAt(left), map.get(s.charAt(left)) - 1); left++; continue; } map.put(s.charAt(right), times + 1); if(right - left + 1 == k) res++; right++; } return s.length() - k + 1 - res; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ public int numKLenSubstrRepeats (String s, int k) { // write code here int sum=0; ArrayList<Character> list=new ArrayList<>(); //依次进行判断 for(int i=0;i+k<=s.length();i++){ //如果该截取的字符串有重复的就sum++ if(dc(s.substring(i,i+k))==true){ sum++; } } return sum; } public boolean dc(String str){ //HashSet进行查重 HashSet<Character> set=new HashSet<>(); for(int i=0;i<str.length();i++){ if(!set.contains(str.charAt(i))){ set.add(str.charAt(i)); }else{ //有重复 return true; } } //无重复 return false; } }
package main import _"fmt" /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ func numKLenSubstrRepeats( s string , k int ) int { cnt:=map[byte]int{} ans:=0 for i,ch:=range []byte(s){ if i==k{ break } cnt[ch]++ } if len(cnt)<k{ ans++ } for l,r:=0,k;r<len(s);l,r=l+1,r+1{ var key byte key=byte(s[l]) if cnt[key]==1{ delete(cnt,key) }else{ cnt[key]-- } key=byte(s[r]) cnt[key]++ if len(cnt)<k{ ans++ } } return ans }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ public int numKLenSubstrRepeats (String s, int k) { // write code here int ans = 0, flag = 0; int[] cnts = new int[26]; for (int i = 0; i < s.length(); i++) { if (++cnts[s.charAt(i) - 'a'] == 2) ++flag; if (i < k - 1) continue; if (i >= k && --cnts[s.charAt(i - k) - 'a'] == 1) --flag; if (flag > 0) ++ans; } return ans; } }
bool isCover(unordered_map<char, int>&mp){ for(auto & it:mp){ if(it.second>1){ return true; } } return false; } //20220728,类似覆盖子串; int numKLenSubstrRepeats(string s, int k) { unordered_map<char, int>mp; int left=0,right=0; int res=0; while(right<s.size()){ mp[s[right]]++; //满足的条件中(含有重复子串),逐渐移动左指针,找到长度为k的子串 while(right-left+1 >=k && isCover(mp)){ if(right-left+1 ==k){ res++; } mp[s[left]]--; left++; } right++; } return res; }
class Solution: def numKLenSubstrRepeats(self , s , k ): # write code here count = 0 l = 0 while l+k <= len(s): sub = s[l:l+k] # 检查是否有重复字符 repeated = False d = {} for ch in sub: if ch in d: repeated = True break else: d[ch] = 1 if repeated: count += 1 l += 1 return count
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ public int numKLenSubstrRepeats (String s, int k) { // write code here int ans = 0; int n = s.length(); if(k>n) return 0; HashMap<Character,Integer> h = new HashMap<Character,Integer>(); for(int i=0; i < k; i++){ if(h.containsKey(s.charAt(i))){ h.put(s.charAt(i),h.get(s.charAt(i))+1); }else{ h.put(s.charAt(i),1); } } if(h.size()<k) ans++; // 开启循环 for(int i=k; i < n; i++){ //出表 if(h.get(s.charAt(i-k))==1){ h.remove(s.charAt(i-k)); }else{ h.put(s.charAt(i-k),h.get(s.charAt(i-k))-1); } //进表 if(h.containsKey(s.charAt(i))){ h.put(s.charAt(i),h.get(s.charAt(i))+1); }else{ h.put(s.charAt(i),1); } // 统计 if(h.size()<k) ans++; } return ans; } }
int numKLenSubstrRepeats(string s, int k) { int cnt = 0;//子串个数 //设置滑动窗口边界 int left = 0;//左边界,初始化为0 int right = k - 1;//右边界,初始化为k-1 set<char> searchBlock;//滑动窗口,即长度为k的子串 for(int i = 0; i < s.length() - k + 1; i++) { for(int j = left; j <= right; j++) { searchBlock.insert(s[j]);//将长度为k的子串插入到set容器中 } if(searchBlock.size() < k)//若set容器中的元素个数小于k,则说明其中含有重复元素,计数+1 { cnt++; } left++;//滑块窗口向右移动 right++;//滑块窗口向右移动 searchBlock.clear();//清空滑动窗口 } return cnt; }