【Leetcode 2273 】 移除字母异位词后的结果数组 —— 三种版本,时间击败100%,空间击败100%

本文主要是介绍【Leetcode 2273 】 移除字母异位词后的结果数组 —— 三种版本,时间击败100%,空间击败100%,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

  1. 0 < i < words.length
  2. 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] 由小写英文字母组成

第一版本 

执行用时:97 ms, 在所有 Typescript 提交中击败了 - %的用户
内存消耗:59.62 MB, 在所有 Typescript 提交中击败了 - %的用户

/*
第一版本
https://leetcode.cn/u/cshappyeveryday/
执行用时:97 ms, 在所有 Typescript 提交中击败了 - %的用户
内存消耗:59.62 MB, 在所有 Typescript 提交中击败了 - %的用户
时间复杂度:O(n*m)
2024年8月30日 
*/
function removeAnagrams(words: string[]): string[] {const OFFSET = "a".charCodeAt(0);let sucP = 1;//二维数组存储每个字符的charCodeconst twoDimension = new Array(words.length).fill([]).map(() => new Array(26).fill(0));for (let i = 0; i < words.length; i++) {for (const char of words[i]) {twoDimension[i][char.charCodeAt(0) - OFFSET]++;}}for (let i = 1; i < words.length; i++) {//判断两个内容是否完全相等const diff = twoDimension[i].filter((n, j) => n === twoDimension[i - 1][j]);if (diff.length === twoDimension[i].length) continue;//在原数组上保存结果数据words[sucP++] = words[i];}return words.slice(0, sucP);
}

第二版本


执行用时:75 ms, 在所有 Typescript 提交中击败了 60.00 %的用户
内存消耗:55.16 MB, 在所有 Typescript 提交中击败了 100.00 %的用户 

/*
第二版本
https://leetcode.cn/u/cshappyeveryday/
执行用时:75 ms, 在所有 Typescript 提交中击败了 60.00 %的用户
内存消耗:55.16 MB, 在所有 Typescript 提交中击败了 100.00 %的用户
时间复杂度:O(n*m)
2024年8月30日 
*/
function removeAnagrams2(words: string[]): string[] {const OFFSET = "a".charCodeAt(0);let sucP = 1;for (let i = 1; i < words.length; i++) {let curWordCode = new Array(26).fill(0);let preWordCode = new Array(26).fill(0);//每一次都计算当前与上一次的charCodefor (const word of words[i]) {curWordCode[word.charCodeAt(0) - OFFSET]++;}for (const word of words[i - 1]) {preWordCode[word.charCodeAt(0) - OFFSET]++;}const isSame = curWordCode.every((n, j) => n === preWordCode[j]);if (isSame) continue;words[sucP++] = words[i];}return words.slice(0, sucP);
}

最终版本

执行用时:67 ms, 在所有 Typescript 提交中击败了 100.00 %的用户

内存消耗:54.29 MB, 在所有 Typescript 提交中击败了 100.00 %的用户

/*
最终版本
https://leetcode.cn/u/cshappyeveryday/
执行用时:67 ms, 在所有 Typescript 提交中击败了 100.00 %的用户
内存消耗:54.29 MB, 在所有 Typescript 提交中击败了 100.00 %的用户
时间复杂度:O(n * m)
2024年8月30日 
*/
function removeAnagrams3(words: string[]): string[] {const OFFSET = "a".charCodeAt(0);let sucP = 1; //成功指针,指向words,该指针前面的元素都是结果let curWordCode = new Array<number>(26).fill(0); //当前 wordCodelet preWordCode = new Array<number>(26).fill(0); //上一个wordCode// 初始化 preWordCodefor (const word of words[0]) {preWordCode[word.charCodeAt(0) - OFFSET]++;}for (let i = 1; i < words.length; i++) {//去除和上一个相同的,注意:这里的去重与 Set() 去重不同。Set会将所有相同的去除,这里只针对相邻的两个if (words[i] === words[i - 1]) continue;curWordCode = new Array<number>(26).fill(0);for (const word of words[i]) {curWordCode[word.charCodeAt(0) - OFFSET]++;}//判断上一次成功的值与本次是否为 字母内容相同的const isSame =curWordCode.length === preWordCode.length &&curWordCode.every((n, j) => n === preWordCode[j]);//   是则证明不是 字母异位词,跳过if (isSame) continue;// 不是,则证明是 字母异位词,则 preWordCode 变成本次wordpreWordCode = [...curWordCode];//修改 结果,将成功指针后移words[sucP++] = words[i];}//依据 sucP 的位置返回结果return words.slice(0, sucP);
}

这篇关于【Leetcode 2273 】 移除字母异位词后的结果数组 —— 三种版本,时间击败100%,空间击败100%的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121907

相关文章

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

如何将Python彻底卸载的三种方法

《如何将Python彻底卸载的三种方法》通常我们在一些软件的使用上有碰壁,第一反应就是卸载重装,所以有小伙伴就问我Python怎么卸载才能彻底卸载干净,今天这篇文章,小编就来教大家如何彻底卸载Pyth... 目录软件卸载①方法:②方法:③方法:清理相关文件夹软件卸载①方法:首先,在安装python时,下

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col