comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
简单 |
1294 |
第 293 场周赛 Q1 |
|
给你一个下标从 0 开始的字符串 words
,其中 words[i]
由小写英文字符组成。
在一步操作中,需要选出任一下标 i
,从 words
中 删除 words[i]
。其中下标 i
需要同时满足下述两个条件:
0 < i < words.length
words[i - 1]
和words[i]
是 字母异位词 。
只要可以选出满足条件的下标,就一直执行这个操作。
在执行所有操作后,返回 words
。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb"
是 "abdc"
的一个字母异位词。
示例 1:
输入:words = ["abba","baba","bbaa","cd","cd"] 输出:["abba","cd"] 解释: 获取结果数组的方法之一是执行下述步骤: - 由于 words[2] = "bbaa" 和 words[1] = "baba" 是字母异位词,选择下标 2 并删除 words[2] 。 现在 words = ["abba","baba","cd","cd"] 。 - 由于 words[1] = "baba" 和 words[0] = "abba" 是字母异位词,选择下标 1 并删除 words[1] 。 现在 words = ["abba","cd","cd"] 。 - 由于 words[2] = "cd" 和 words[1] = "cd" 是字母异位词,选择下标 2 并删除 words[2] 。 现在 words = ["abba","cd"] 。 无法再执行任何操作,所以 ["abba","cd"] 是最终答案。
示例 2:
输入:words = ["a","b","c","d","e"] 输出:["a","b","c","d","e"] 解释: words 中不存在互为字母异位词的两个相邻字符串,所以无需执行任何操作。
提示:
1 <= words.length <= 100
1 <= words[i].length <= 10
words[i]
由小写英文字母组成
我们首先将
问题转换为判断两个字符串是否是字母异位词,我们定义一个辅助函数
在函数
时间复杂度
class Solution:
def removeAnagrams(self, words: List[str]) -> List[str]:
def check(s: str, t: str) -> bool:
if len(s) != len(t):
return True
cnt = Counter(s)
for c in t:
cnt[c] -= 1
if cnt[c] < 0:
return True
return False
return [words[0]] + [t for s, t in pairwise(words) if check(s, t)]
class Solution {
public List<String> removeAnagrams(String[] words) {
List<String> ans = new ArrayList<>();
ans.add(words[0]);
for (int i = 1; i < words.length; ++i) {
if (check(words[i - 1], words[i])) {
ans.add(words[i]);
}
}
return ans;
}
private boolean check(String s, String t) {
if (s.length() != t.length()) {
return true;
}
int[] cnt = new int[26];
for (int i = 0; i < s.length(); ++i) {
++cnt[s.charAt(i) - 'a'];
}
for (int i = 0; i < t.length(); ++i) {
if (--cnt[t.charAt(i) - 'a'] < 0) {
return true;
}
}
return false;
}
}
class Solution {
public:
vector<string> removeAnagrams(vector<string>& words) {
auto check = [](string& s, string& t) -> bool {
if (s.size() != t.size()) {
return true;
}
int cnt[26]{};
for (char& c : s) {
++cnt[c - 'a'];
}
for (char& c : t) {
if (--cnt[c - 'a'] < 0) {
return true;
}
}
return false;
};
vector<string> ans = {words[0]};
for (int i = 1; i < words.size(); ++i) {
if (check(words[i - 1], words[i])) {
ans.emplace_back(words[i]);
}
}
return ans;
}
};
func removeAnagrams(words []string) []string {
ans := []string{words[0]}
check := func(s, t string) bool {
if len(s) != len(t) {
return true
}
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
}
for _, c := range t {
cnt[c-'a']--
if cnt[c-'a'] < 0 {
return true
}
}
return false
}
for i, t := range words[1:] {
if check(words[i], t) {
ans = append(ans, t)
}
}
return ans
}
function removeAnagrams(words: string[]): string[] {
const ans: string[] = [words[0]];
const check = (s: string, t: string): boolean => {
if (s.length !== t.length) {
return true;
}
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
++cnt[c.charCodeAt(0) - 97];
}
for (const c of t) {
if (--cnt[c.charCodeAt(0) - 97] < 0) {
return true;
}
}
return false;
};
for (let i = 1; i < words.length; ++i) {
if (check(words[i - 1], words[i])) {
ans.push(words[i]);
}
}
return ans;
}