• 作者: 负雪明烛
  • id: fuxuemingzhu
  • 公众号:每日算法题
  • 本文关键词:LeetCode,力扣,算法,算法题,字符串,并查集,刷题群

题目地址:https://leetcode-cn.com/problems/similar-string-groups/

题目描述

如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 XY 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。

例如,对于 [“tars”, “rats”, “arts”, “star”] 这四个字符串而言:

  • tars” 和 “rats” 是相似的 (交换 0 与 2 的位置); “rats” 和 “arts” 也是相似的。
  • 但是 “star” 不与 [“tars”,“rats”,“arts”] 中的任意一个相似,因为无法通过交换 star 中的两个不同位置字母得到三者的任意一个。

总之,它们通过相似性形成了两个关联组:{“tars”, “rats”, “arts”} {“star”}。注意,“tars”“arts” 是在同一组中,即使它们并不相似。形式上,对每个组而言,要确定一个单词在组中,只需要这个词和该组中至少一个单词相似。

给你一个字符串列表 strs 。列表中的每个字符串都是 strs 中其它所有字符串的一个字母异位词。请问 strs 中有多少个 相似字符串组

示例:

输入:strs = [“tars”,“rats”,“arts”,“star”]
输出:2
解释:如题目上文所解释,可以分为 {“tars”, “rats”, “arts”} 和 {“star”} 两个相似字符串组。

解题思路

并查集

今天的题目的中文题意比较模糊,我看了很久才明白相似字符串组的含义。即相似字符串组中的每个字符串都有另外至少一个字符串和它相似。比如对于 {“tars”, “rats”, “arts”} 这个相似字符串组而言,相似关系是 “tars” <=> “rats” <=> “arts”

两个字符串相似的含义是能够通过交换两个字符的位置,得到另外一个字符串。判断两个字符串相似的时间的复杂度是 O(N),因为把所有位置遍历一次,统计两个字符串的对应位置有多少不等即可。

明白了题意之后,做法也就呼之欲出了:把每个字符串当做图中的一个节点,如果两个字符串相似,那么它们之间就有一条边。图中的每个连通区域是一个相似字符串组。问:图中有多少个不连通的区域?

很显然,图的连通性问题可以用「并查集」去做。然后套「并查集」的模板就可以了。

这也是我之前说的:“在明白题目考察什么之后,剩下的就是套模板”。

和今天题目非常类似的题目是「1579. 保证图可完全遍历」,我前几天的文章已经详细分析过了,两者都是考察图中有多少个连通区域,都是直接使用并查集模板。

代码

每个字符串都是一个节点,我们需要分析每两个节点之间是否相似,如果相似就添加一条边,使用并查集,看最终有多少个连通区域。

代码思路:

  1. 两重 for 循环,实现对节点之间两两组合,判断两个节点是否相似;
  2. 判断相似的方法是:两个字符串的对应位置中只有 0 个或者 2 个不同;
  3. 如果两个字符串相似则使用并查集,将此两个节点之间连通上一条边;
  4. 统计最终并查集中有多少个不同的连通区域,即为所求。

使用 Python2 写的代码如下。

class Solution(object):
def numSimilarGroups(self, strs):
"""
:type strs: List[str]
:rtype: int
"""
N = len(strs)
dsu = DSU(N)
for i in range(N):
for j in range(i + 1, N):
if self.isSimilar(strs[i], strs[j]):
dsu.union(i, j)
return dsu.regions() def isSimilar(self, str1, str2):
count = 0
for i in range(len(str1)):
if str1[i] != str2[i]:
count += 1
return count == 2 or count == 0 class DSU:
def __init__(self, N):
self.par_ = range(N + 1)
self.regions_ = N def find(self, x):
if x != self.par_[x]:
self.par_[x] = self.find(self.par_[x])
return self.par_[x] def union(self, x, y):
px = self.find(x)
py = self.find(y)
if px == py:
return
self.par_[px] = py
self.regions_ -= 1 def regions(self):
return self.regions_

刷题心得

今天的题目考察并查集,仍然是可以直接套模板。本周已经连续考察了多个并查集问题,相信大家已经掌握了模板。昨天有群友说,感谢每日一题连续这么多次都是并查集题目,他现在已经能够背下来模板了。这也是大家的算法成长过程。刷题一定要坚持呀!

力扣题目一般是单一考点,即每个题目只考察一个知识点。因此做每个题目时,有一半的工作量是在思考这个题目在考察什么,剩下的一半工作量就是在套模板。把题目抽象成具体考察点的能力需要我们经常练习,也是靠多刷题来获得,当然啦,多看看每日算法题的解题思路,也会对大家很有帮助的!

OK,这就是本次题解的全部内容了,如果你觉得我的题解对你有帮助的话,求赞、求关注、求转发、求在看。你的认可就是我前进的最大动力!我们明天再见!

欢迎加入组织

算法每日一题是个互相帮助、互相监督的力扣打卡网站,其地址是 https://www.ojeveryday.com/

想加入千人刷题群的朋友,可以复制上面的链接到浏览器,然后在左侧点击“加入组织”,提交力扣个人主页,即可进入刷题群。期待你早日加入。

欢迎关注我的公众号:每日算法题

日期

2021 年 1 月 31 日 —— 周末加油!努力!

【LeetCode】839. 相似字符串组 Similar String Groups (Python)的更多相关文章

  1. [Swift]LeetCode839. 相似字符串组 | Similar String Groups

    Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it ...

  2. Similar String Groups

    Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it ...

  3. [LeetCode] 839. Similar String Groups 相似字符串组

    Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it ...

  4. leetcode 839 Similar String Groups

    题目 Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that ...

  5. LeetCode 394:字符串解码 Decode String

    题目: 给定一个经过编码的字符串,返回它解码后的字符串. Given an encoded string, return its decoded string. 编码规则为: k[encoded_st ...

  6. LeetCode 541. 反转字符串 II(Reverse String II)

    541. 反转字符串 II 541. Reverse String II

  7. leetcode 【 Reverse Words in a String 】python 实现

    题目: Given an input string, reverse the string word by word. For example,Given s = "the sky is b ...

  8. LeetCode.893-特殊相等字符串组(Groups of Special-Equivalent Strings)

    这是悦乐书的第344次更新,第368篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第209题(顺位题号是893). You are given an array A of ...

  9. [Swift]LeetCode893. 特殊等价字符串组 | Groups of Special-Equivalent Strings

    You are given an array A of strings. Two strings S and T are special-equivalent if after any number ...

随机推荐

  1. Shell 指定行处理head、tail、sed

    目录 Shell 指定行处理 head.tail.sed head 前几行 tail sed 删除.替换.新增.选取 案例 删除行 插入行 查看某行 替换某行 部分数据的查找并替换 读写操作 Shel ...

  2. 面向Web应用的并发压力测试工具——Locust实用攻略

    1. 概述 该方案写作目的在于描述一个基于Locust实现的压力测试,文中详细地描述了如何利用locustfile.py文件定义期望达成的测试用例,并利用Locust对目标站点进行并发压力测试. 特别 ...

  3. Portrait Photography Beginners Guide

    Please visit photoandtips稻糠亩 for more information. 六级/考研单词: vogue, derive, gorgeous, thereby, strict ...

  4. accent, accept

    accent A colon (:) is used to represent a long vowel, e.g. sheet /ʃiːt/ and shit /ʃit/. The word bed ...

  5. 数据库时间和 java 时间不一致解决方案

    java添加 date 到数据库,时间不一致 使用 date 添加到数据库,数据库显示的时候和date时间相差 8 个小时,这是由于 mysql 上的时区的问题,这里有两个解决方案: 方案一: 设置数 ...

  6. Angular 组件通信的三种方式

    我们可以通过以下三种方式来实现: 传递一个组件的引用给另一个组件 通过子组件发送EventEmitter和父组件通信 通过serive通信 1. 传递一个组件的引用给另一个组件 Demo1 模板引用变 ...

  7. ES6必知,箭头函数与普通函数的区别。

    1. 箭头函数没有prototype(原型),所以箭头函数本身没有this let a = () =>{}; console.log(a.prototype); // undefined 2. ...

  8. [JAVA]动态代理与AOP的千丝万缕

    动态代理与AOP的联系 别的不说,直接上图 首先是AOP切面编程 什么是切面?(自己心里想想就ok)所以所谓的切面编程,你也就懂得大体了,只是这个被切的是个程序而已 那么AOP与动态代理有什么关系呢? ...

  9. Linux基础命令---exportfs管理挂载的nfs文件系统

    exportfs exportfs主要用于管理当前NFS服务器的文件系统. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法        /usr/sb ...

  10. When do we pass arguments by reference or pointer?

    在C++中,基于以下如下我们通过以引用reference的形式传递变量. (1)To modify local variables of the caller function A reference ...