LeetCode - 893 - 特殊等价字符串组(groups-of-special-equivalent-strings)

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 前言
三 解题及测试
四 LeetCode Submit
五 解题思路
六 进一步思考

二 前言

  • 难度:简单

  • 涉及知识:字符串

  • 题目地址:https://leetcode-cn.com/problems/groups-of-special-equivalent-strings/

  • 题目内容

你将得到一个字符串数组 A。

如果经过任意次数的移动,S == T,
那么两个字符串 S 和 T 是特殊等价的。

一次移动包括选择两个索引 i 和 j,
且 i % 2 == j % 2,交换 S[j] 和 S [i]。

现在规定,A 中的特殊等价字符串组是 A 的非空子集 S,
这样不在 S 中的任何字符串与 S 中的任何字符串都不是特殊等价的。

返回 A 中特殊等价字符串组的数量。

示例 1:

输入:["a","b","c","a","c","c"]
输出:3
解释:3 组 ["a","a"],["b"],["c","c","c"]

示例 2:

输入:["aa","bb","ab","ba"]
输出:4
解释:4 组 ["aa"],["bb"],["ab"],["ba"]

示例 3:

输入:["abc","acb","bac","bca","cab","cba"]
输出:3
解释:3 组 ["abc","cba"],["acb","bca"],["bac","cab"]

示例 4:

输入:["abcd","cdab","adcb","cbad"]
输出:1
解释:1 组 ["abcd","cdab","adcb","cbad"]

提示:

1 <= A.length <= 1000
1 <= A[i].length <= 20
所有 A[i] 都具有相同的长度。
所有 A[i] 都只由小写字母组成。

三 解题及测试

小伙伴可以先自己在本地尝试解题,再回来看看 jsliang 的解题思路。

  • LeetCode 给定函数体

/**
 * @param {string[]} A
 * @return {number}
 */
var numSpecialEquivGroups = function(A) {

};

根据上面的已知函数,尝试破解本题吧~

确定了自己的答案再看下面代码哈~

index.js

/**
 * @name 特殊等价字符串组
 * @param {string[]} A
 * @return {number}
 */
const numSpecialEquivGroups = (A) => {
  return [...new Set(A.map((item) => item.split('').filter((t, i) => i % 2 === 1).sort().join('') + item.split('').filter((t, i) => i % 2 === 0).sort().join('')))].length;
};

console.log(numSpecialEquivGroups(['abc', 'acb', 'bac', 'bca', 'cab', 'cba']));

node index.js 返回:

3

四 LeetCode Submit

Accepted
* 36/36 cases passed (76 ms)
* Your runtime beats 97.3 % of javascript submissions
* Your memory usage beats 26.67 % of javascript submissions (37.7 MB)

五 解题思路

首先,不管有的没的,先猜测如果暴力破解这道题,那么损耗一定不低,甚至有可能超时!

分析题意:

  1. 有一个数组 A,它由 n 个相同长度的小写字母组成;

  2. 数组 A 的长度在 [1, 1000] 之间;

  3. 数组 A 中字符的长度在 [1, 20] 之间。

假设有数组:

  • ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

那么,如何判断是否有【特殊等价】字符呢?

有的,根据题意:

如果经过任意次数的移动,
S == T,
那么两个字符串 S 和 T 是特殊等价的。

一次移动包括选择两个索引 i 和 j,
且 i % 2 == j % 2,
交换 S[j] 和 S [i]。

这道题的意思是,在单个字符中:

  1. 奇数索引只能和奇数索引交换;

  2. 偶数索引只能和偶数索引交换。

例如:acb,那么只能 ab 交换为 bca。(因为 a 索引为 0 ,b 索引为 2,两者 % 2 都为 0)。

题目中的表达即奇偶不能互换。

依次,我们可以顺势做出暴力破解:

暴力破解

// ...好吧我做不出来

怀疑人生,这真的是【简单】难度?

六 进一步思考

看了下题解,有个 JavaScript 的解题还不错:

  • 题目, 我该拿什么拯救你?:https://leetcode-cn.com/problems/groups-of-special-equivalent-strings/solution/ti-mu-wo-gai-na-shi-yao-zheng-jiu-ni-by-shetia/

其实:

  1. 有个数组, 元素是字符串;

  2. 字符串中的字符两两交换,交换的字符索引满足 i % 2 == j % 2,就是说 奇跟奇, 偶跟偶 交换;

  3. 不管交换多少次, 只要 字符串交换后 有和 另一个字符串交换 后 相同, 就为等价的;

  4. 把这些等价的字符串归为 一个数组中;

  5. 求 有多少个这样的数组;

既然 奇跟奇, 偶跟偶 交换, 我们何不 把字符串的字符索引为 奇 和 偶 的分离开来, 各放到一个数组中

然后 奇 偶 数组排序下, 再拼接起来, 如果它们是 特殊等价 的话, 这样的处理下来, 得到的就会是 完全相等的字符串

//如:
A = ["abcd","cdab","adcb","cbad"]

// 奇偶分离
A = [
      [['a','c'],['b','d']],
      [['c','a'],['d','b']],
      [['a','c'],['d','b']],
      [['c','a'],['b','d']]
    ]

// 排序
A = [
      [['a','c'],['b','d']],
      [['a','c'],['b','d']],
      [['a','c'],['b','d']],
      [['a','c'],['b','d']]
    ]

// 拼接
A = ['abcd','abcd','abcd','abcd']

// 去重
A = ['abcd']

// 返回长度即可

所以有了题解:

var numSpecialEquivGroups = function(A) {
 let list = A.map(item => {
   let arr = item.split('')
   let odd = arr.filter((t,i) => i%2===1).sort().join('')
   let event = arr.filter((t,i) => i%2===0).sort().join('')
   return event+odd
 })
 return [...new Set(list)].length
};

当然,尽信代码不如无码,所以 jsliang 进行了强压缩:

const numSpecialEquivGroups = (A) => [...new Set(A.map((item) => item.split('').filter((t, i) => i % 2 === 1).sort().join('') + item.split('').filter((t, i) => i % 2 === 0).sort().join('')))].length;

Submit 提交为:

Accepted
* 36/36 cases passed (76 ms)
* Your runtime beats 97.3 % of javascript submissions
* Your memory usage beats 26.67 % of javascript submissions (37.7 MB)

以上~

如果小伙伴有更好的思路想法,欢迎评论留言或者私聊 jsliang~


不折腾的前端,和咸鱼有什么区别!

jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。

浪子神剑 会每天更新面试题,以面试题为驱动来带动大家学习,坚持每天学习与思考,每天进步一点!

扫描上方二维码,关注 jsliang 的公众号(左)和 浪子神剑 的公众号(右),让我们一起折腾!

jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于https://github.com/LiangJunrong/document-library上的作品创作。
本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值