写点什么

【LeetCode】 移除字母异位词后的结果数组 Java 题解

作者:HQ数字卡
  • 2022 年 6 月 21 日
  • 本文字数:1589 字

    阅读完需:约 5 分钟

题目描述

给你一个下标从 0 开始的字符串 words ,其中 words[i] 由小写英文字符组成。


在一步操作中,需要选出任一下标 i ,从 words 中 删除 words[i] 。其中下标 i 需要同时满足下述两个条件:


0 < i < words.lengthwords[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)

  • 坚持算法每日一题,加油!

发布于: 2 小时前阅读数: 4
用户头像

HQ数字卡

关注

还未添加个人签名 2019.09.29 加入

LeetCode,略懂后端的RD

评论

发布
暂无评论
【LeetCode】 移除字母异位词后的结果数组Java题解_LeetCode_HQ数字卡_InfoQ写作社区