1. 程式人生 > 其它 >Leecode no.438 找到字串中所有字母異位詞

Leecode no.438 找到字串中所有字母異位詞

package leecode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 438. 找到字串中所有字母異位詞
*
* 給定兩個字串s和 p,找到s中所有p的異位詞的子串,返回這些子串的起始索引。不考慮答案輸出的順序。
*
* 異位詞 指由相同字母重排列形成的字串(包括相同的字串)。
*
*
* @author Tang
* @date 2021/12/6
*/
public class FindAnagrams {


/**
* 滑動視窗
*
* @param s
* @param p
* @return
*/
public List<Integer> findAnagrams(String s, String p) {
char[] all = s.toCharArray();
char[] target = p.toCharArray();

List<Integer> result = new ArrayList<>();

//構建needMap
Map<Character, Integer> needMap = new HashMap<>();
for (char c : target) {
needMap.put(c, needMap.getOrDefault(c, 0) + 1);
}
//構建window
Map<Character, Integer> window = new HashMap<>();

//視窗左右指標
//視窗左畢右開原則
int left = 0;
int right = 0;

//當前視窗中滿足了 有幾個元素滿足了need需要的數量
// 0 <= valid <= needMap.size
int valid = 0;

//以視窗右邊界走到頭為限制
while(right < all.length) {
char c = all[right];
right++;

//判斷c是否需要
if(needMap.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) +1);

//判斷c元素是否達到需求數量
if(window.get(c).equals(needMap.get(c))) {
valid++;
}
}

//判斷左縮視窗條件
if(right - left == target.length) {
//判斷是否滿足need全部要求
//加入結果
if(valid == needMap.size()) {
result.add(left);
}

//左縮視窗
char d = all[left];
left++;
if(needMap.containsKey(d)) {
if(window.get(d).equals(needMap.get(d))) {
valid--;
}
window.put(d, window.get(d) - 1);
}
}
}

return result;

}

public static void main(String[] args) {

}


}