【Lintcode】284. Matching Subsequences
阿新 • • 發佈:2020-12-26
技術標籤:# 棧、佇列、串及其他資料結構leetcode字串演算法java資料結構
題目地址:
https://www.lintcode.com/problem/matching-subsequences/description
給定一個長 n n n的字串 s s s,再給定若干詢問,每次詢問一個字串 w w w是否是 s s s的子序列。
思路是序列自動機。可以模仿https://blog.csdn.net/qq_46105170/article/details/111661192來做。程式碼如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
/**
* @param source: A string
* @param words: A list of string
* @return: return list of words[i] that is a subsequence of source.
*/
public List<String> MatchingSubsequences(String source, List<String> words) {
// write your code here
List<String> res = new ArrayList<>();
// auto[i][k]表示的是source[i - 1]之後字元k首次出現的位置是第幾(從1開始計數)
int[][] auto = new int[source.length() + 1][128];
// -1是不合法狀態,先將每個entry都初始化為-1
for (int[] row : auto) {
Arrays.fill(row, -1);
}
// 求解auto可以用動態規劃來做
for (int i = source.length() - 1; i >= 0; i--) {
for (int j = 0; j < 128; j++) {
auto[i][j] = auto[i + 1][j];
}
auto[i][source.charAt(i)] = i + 1;
}
for (String word : words) {
int idx = 0;
for (int i = 0; i < word.length() && idx != -1; i++) {
idx = auto[idx][word.charAt(i)];
}
if (idx != -1) {
res.add(word);
}
}
return res;
}
}
預處理時間複雜度 O ( n ) O(n) O(n),每次詢問時間 O ( l w ) O(l_w) O(lw),空間 O ( n ) O(n) O(n)。
暴力法當然也是可以做的。程式碼如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
/**
* @param source: A string
* @param words: A list of string
* @return: return list of words[i] that is a subsequence of source.
*/
public List<String> MatchingSubsequences(String source, List<String> words) {
// write your code here
// idx[i]代表words[i]這個查詢串已經匹配到什麼下標了
int[] idx = new int[words.size()];
for (int i = 0; i < source.length(); i++) {
for (int j = 0; j < words.size(); j++) {
// 若已經匹配則跳過
if (idx[j] == -1) {
continue;
}
// 如果查詢串words[j]能和當前的source[i]匹配,則後移匹配位置
if (words.get(j).charAt(idx[j]) == source.charAt(i)) {
idx[j]++;
}
// 如果查詢串words[j]匹配成功了,標記為-1
if (idx[j] == words.get(j).length()) {
idx[j] = -1;
}
}
}
// 遍歷一遍idx陣列,將匹配成功的加入答案
List<String> res = new ArrayList<>();
for (int i = 0; i < words.size(); i++) {
if (idx[i] == -1) {
res.add(words.get(i));
}
}
return res;
}
}
時間複雜度 O ( n k ) O(nk) O(nk), k k k為詢問次數。由於一般而言詢問字串長度是遠小於 n n n的,所以暴力法的複雜度是比自動機更高的。