持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
题目描述
给你一个下标从 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 中不存在互为字母异位词的两个相邻字符串,所以无需执行任何操作。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-resultant-array-after-removing-anagrams
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
- 今天的算法题目是数组处理题目,题目比较长,分析重点如下。1. 求字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次,这里需要注意的是,两个单词完全相同也是异位词。2. 当连续的两个单词是异位词的时候,删除前一个。
- 根据如上分析,我们首先实现字母异位词的代码判断,判断的时候,由于都是小写字母,我们可以使用ASCII知识。什么是 ASCII?ASCII 码是一套编码规范,其中97~122号为26个小写英文字母。用数组记录字符出现的次数。遍历过后,当数组出现次数都是 0 的时候,两个单词即为字母异位词。
- 做这个题目时候,通过观察,字母异位词可以传递,因此,我们只保留当前的单词即可。这一步很重要,不容易想到,我也是参考题解才学会的,需要好好思考。具体实现代码如下,供参考。
通过代码
class Solution {
public List<String> removeAnagrams(String[] words) {
List<String> ans = new ArrayList<>();
int n = words.length;
ans.add(words[0]);
for (int i = 1; i < n; i++) {
if (check(words[i - 1], words[i])){
continue;
}
ans.add(words[i]);
}
return ans;
}
private boolean check(String word1, String word2) {
boolean ans = false;
if (word1.equals(word2)) {
ans = true;
return ans;
}
int n1 = word1.length();
int n2 = word2.length();
if (n1 != n2) {
return ans;
}
int n = 26;
int[] cnt = new int[n];
for (int j = 0; j < n1; j++) {
cnt[word1.charAt(j) - 'a']++;
cnt[word2.charAt(j) - 'a']--;
}
for (int k = 0; k < n; k++) {
if (cnt[k] != 0) {
return ans;
}
}
ans = true;
return ans;
}
}
总结
- 上述算法的时间复杂度是O(n),空间复杂度是O(n)
- 坚持算法每日一题,加油!