LeetCode Top 100 Liked Questions 438. Find All Anagrams in a String (Java版; Medium)

mac2024-12-04  47

welcome to my blog

LeetCode Top 100 Liked Questions 438. Find All Anagrams in a String (Java版; Medium)

题目描述

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. The order of output does not matter. Example 1: Input: s: "cbaebabacd" p: "abc" Output: [0, 6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc". Example 2: Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab". 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> list = new ArrayList<>(); HashMap<Character, Integer> map = new HashMap<>(); for(int i=0; i<p.length(); i++){ char ch = p.charAt(i); map.put(ch, map.getOrDefault(ch, 0)-1); } int left=0, right=0; int count = 0; while(right<s.length()){ char ch = s.charAt(right); if(map.containsKey(ch)){ map.put(ch, map.get(ch)+1); if(map.get(ch)==0){ count++; } } while(count==map.size()){ if(right - left + 1 == p.length()){ list.add(left); } char ch2 = s.charAt(left); if(map.containsKey(ch2)){ map.put(ch2, map.get(ch2)-1); if(map.get(ch2)==-1){ count--; } } left++; } right++; } return list; } }

第一次做; 双指针法:先移动right,满足条件后,再移动left; count变量记录有多少个字符满足数量要求了; 判断两个Integer类型的变量是否相等,得用equals()方法!! 不能用==, 但是可以用<或者>

import java.util.ArrayList; import java.util.HashMap; class Solution { public List<Integer> findAnagrams(String s, String p) { ArrayList<Integer> res = new ArrayList<>(); if(s.length() < p.length()) return res; // HashMap<Character, Integer> needs = new HashMap<>(); HashMap<Character, Integer> window = new HashMap<>(); //核心:记录window中有多少个符合要求的字符, 这个变量实现了O(1)是否window是否有效,最开始没有想到 int count = 0; //创建needs for(int i=0; i<p.length(); i++) needs.put(p.charAt(i), needs.getOrDefault(p.charAt(i),0)+1); //双指针主体 int left=0, right=0; while(right<s.length()){ char ch = s.charAt(right); if(needs.containsKey(ch)){ window.put(ch, window.getOrDefault(ch,0)+1); //核心:检查ch的数量是否符合要求; //细节: 满足条件后,count只会++一次 //顶级核心:哈希表中的value是Integer类型的,所以这里不能用window.get(ch)==needs.get(ch), 必须用.equals()方法 if(window.get(ch).equals(needs.get(ch))){ count++; } } right++; //核心:while循环条件 while(count==needs.size()){ //核心:if条件 if(right - left == p.length()) res.add(left); char ch2 = s.charAt(left); if(window.containsKey(ch2)){ window.put(ch2, window.get(ch2)-1); //核心:检查ch2的数量是否不再符合要求; /* 错误的想法: 不能用if(window.get(ch2) < needs.get(ch2)) 这样可能导致count执行多次减减, 不对, 实际上可以这么写, 因为count减减后就不满足下一轮循环的执行条件了! */ //细节: 满足if条件后,count只会--一次 if(window.get(ch2) < needs.get(ch2)){ count--; } } left++; } // res.add(left-1); } return res; } }

LeetCode最优解, 只用了一个哈希表, 本质是一样的

public class Solution { public List<Integer> findAnagrams(String s, String t) { List<Integer> result = new LinkedList<>(); if(t.length()> s.length()) return result; Map<Character, Integer> map = new HashMap<>(); for(char c : t.toCharArray()){ map.put(c, map.getOrDefault(c, 0) + 1); } int counter = map.size(); int begin = 0, end = 0; int head = 0; int len = Integer.MAX_VALUE; while(end < s.length()){ char c = s.charAt(end); if( map.containsKey(c) ){ map.put(c, map.get(c)-1); if(map.get(c) == 0) counter--; } end++; while(counter == 0){ char tempc = s.charAt(begin); if(map.containsKey(tempc)){ map.put(tempc, map.get(tempc) + 1); if(map.get(tempc) > 0){ counter++; } } if(end-begin == t.length()){ result.add(begin); } begin++; } } return result; } }

大佬的极致总结, 图末是他的公众号二维码

最新回复(0)