2022-05-08:给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中,每个字母都至多只出现一次。 如果通过以下操作之一,我们可以
2022-05-08:给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中,每个字母都至多只出现一次。
如果通过以下操作之一,我们可以从 s1 的字母集合得到 s2 的字母集合,那么我们称这两个字符串为 关联的 :
往 s1 的字母集合中添加一个字母。
从 s1 的字母集合中删去一个字母。
将 s1 中的一个字母替换成另外任意一个字母(也可以替换为这个字母本身)。
数组 words 可以分为一个或者多个无交集的 组 。如果一个字符串与另一个字符串关联,那么它们应当属于同一个组。
注意,你需要确保分好组后,一个组内的任一字符串与其他组的字符串都不关联。可以证明在这个条件下,分组方案是唯一的。
请你返回一个长度为 2 的数组 ans :
ans[0] 是 words 分组后的 总组数 。
ans[1] 是字符串数目最多的组所包含的字符串数目。
输入:words = [“a”,“b”,“ab”,“cde”]。
输出:[2,3]。
解释:
- words[0] 可以得到 words[1] (将 ‘a’ 替换为 ‘b’)和 words[2] (添加 ‘b’)。所以 words[0] 与 words[1] 和 words[2] 关联。
- words[1] 可以得到 words[0] (将 ‘b’ 替换为 ‘a’)和 words[2] (添加 ‘a’)。所以 words[1] 与 words[0] 和 words[2] 关联。
- words[2] 可以得到 words[0] (删去 ‘b’)和 words[1] (删去 ‘a’)。所以 words[2] 与 words[0] 和 words[1] 关联。
- words[3] 与 words 中其他字符串都不关联。
所以,words 可以分成 2 个组 [“a”,“b”,“ab”] 和 [“cde”] 。最大的组大小为 3 。
力扣2157. 字符串分组。
答案2022-05-08:
并查集。
代码用rust编写。代码如下:
use std::collections::HashMap;
fn main() {
let words: Vec<&str> = vec!["a", "b", "ab", "cde"];
let answer = group_strings2(&words);
println!("answer = {:?}", answer);
}
fn group_strings2(words: &Vec<&str>) -> Vec<isize> {
let n = words.len() as isize;
let mut uf: UnionFind = UnionFind::new(n);
let mut strs: Vec<isize> = vec![];
for _i in 0..n {
strs.push(0);
}
let mut stands: HashMap<isize, isize> = HashMap::new();
for i in 0..n {
let mut status: isize = 0;
for c in words[i as usize].chars() {
status |= 1 << (c as u8 - 'a' as u8);
}
strs[i as usize] = status;
let mut isnone = false;
match stands.get(&status) {
Some(value) => uf.union(*value, i),
None => isnone = true,
}
if isnone {
stands.insert(status, i);
}
}
for i in 0..n {
let yes = strs[i as usize];
let no = (!yes) & ((1 << 26) - 1);
let mut tmp_yes = yes;
let mut tmp_no = no;
let mut right_one_yes;
let mut right_one_no;
// 0....0 0110011
//
// 0....0 0110011
// 0....0 0000001 -> 用
// 0....0 0110010
// 0....0 0000010 -> 用
// 0....0 0110000
while tmp_yes != 0 {
right_one_yes = tmp_yes & (-tmp_yes);
let isok: bool;
match stands.get(&(yes ^ right_one_yes)) {
Some(_value) => isok = true,
None => isok = false,
}
if isok {
uf.union(i, *stands.get(&(yes ^ right_one_yes)).unwrap());
}
tmp_yes ^= right_one_yes;
}
// tmpNo = 该去试试什么添加!
while tmp_no != 0 {
right_one_no = tmp_no & (-tmp_no);
let isok: bool;
match stands.get(&(yes | right_one_no)) {
Some(_value) => isok = true,
None => isok = false,
}
if isok {
uf.union(i, *stands.get(&(yes | right_one_no)).unwrap());
}
tmp_no ^= right_one_no;
}
tmp_yes = yes;
while tmp_yes != 0 {
right_one_yes = tmp_yes & (-tmp_yes);
tmp_no = no;
while tmp_no != 0 {
right_one_no = tmp_no & (-tmp_no);
let isok: bool;
match stands.get(&((yes ^ right_one_yes) | right_one_no)) {
Some(_value) => isok = true,
None => isok = false,
}
if isok {
uf.union(
i,
*stands.get(&((yes ^ right_one_yes) | right_one_no)).unwrap(),
);
}
tmp_no ^= right_one_no;
}
tmp_yes ^= right_one_yes;
}
}
let ans: Vec<isize> = vec![uf.sets(), uf.max_size()];
return ans;
}
pub struct UnionFind {
pub parent: Vec<isize>,
pub size: Vec<isize>,
pub help: Vec<isize>,
}
impl UnionFind {
pub fn new(n: isize) -> UnionFind {
let mut parent: Vec<isize> = vec![];
let mut size: Vec<isize> = vec![];
let mut help: Vec<isize> = vec![];
for i in 0..n {
parent.push(i);
size.push(1);
help.push(0);
}
UnionFind {
parent: parent,
size: size,
help: help,
}
}
pub fn find(&mut self, i: isize) -> isize {
let mut i = i;
let mut hi: isize = 0;
while i != self.parent[i as usize] {
self.help[hi as usize] = i;
hi += 1;
i = self.parent[i as usize];
}
hi -= 1;
while hi >= 0 {
self.parent[self.help[hi as usize] as usize] = i;
hi -= 1;
}
return i;
}
pub fn union(&mut self, i: isize, j: isize) {
let f1 = self.find(i);
let f2 = self.find(j);
if f1 != f2 {
if self.size[f1 as usize] >= self.size[f2 as usize] {
self.size[f1 as usize] += self.size[f2 as usize];
self.parent[f2 as usize] = f1;
} else {
self.size[f2 as usize] += self.size[f1 as usize];
self.parent[f1 as usize] = f2;
}
}
}
pub fn sets(&mut self) -> isize {
let mut ans: isize = 0;
for i in 0..self.parent.len() {
ans += if self.parent[i] == i as isize { 1 } else { 0 };
}
return ans;
}
pub fn max_size(&mut self) -> isize {
let mut ans: isize = 0;
for i in 0..self.size.len() {
ans = if ans > self.size[i as usize] {
ans
} else {
self.size[i as usize]
};
}
return ans;
}
}
执行结果如下:

2022-05-08:给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中,每个字母都至多只出现一次。 如果通过以下操作之一,我们可以的更多相关文章
- 给定两个字符串 s 和 t,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。
给定两个字符串 s 和 t,它们只包含小写字母.字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母.请找出在 t 中被添加的字母. 示例: 输入: s = "abcd" ...
- 获取页面中任意一个元素距离body的偏移量
//offSet:等同于jQuery中的offSet方法,获取页面中任意一个元素距离body的偏移量function offSet(curEle) { var totalLeft = null; va ...
- 【剑指offer】找出数组中任意一个重复的数字,C++实现
原创博文,转载请注明出处! # 题目 # 思路 对于长度为n的数组,范围为0~n-1的数字而言,如果不粗在重复数字,则排序后数组元素和数组角标相同.如果存在重复数字,则在排序的过程中会出现不同下标对应 ...
- 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3
// test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- [Robot Framework] 校验字符串中是否包含某个子字符串,校验同时满足两个条件中任意一个
${tWarningMessage} Run Keyword If ${tIfExist} AutoItLibrary.Win Get Text Generate Fee Data warning m ...
- java 正则表达式 验证字符串 只包含汉字英文数字
String content = “testContent”; String regex="^[a-zA-Z0-9\u4E00-\u9FA5]+$"; Pattern patter ...
- 让android系统中任意一个view变成进度条
1.效果 2.进度条背景drawable文件 结束后可以恢复原背景. <?xml version="1.0" encoding="utf-8"?> ...
- VIM 用正则表达式,非贪婪匹配,匹配竖杠,竖线, 匹配中文,中文正则,倒数第二列, 匹配任意一个字符 :
VIM 用正则表达式 批量替换文本,多行删除,复制,移动 在VIM中 用正则表达式 批量替换文本,多行删除,复制,移动 :n1,n2 m n3 移动n1-n2行(包括n1,n2)到n3行之下: ...
- 只包含schema的dll生成和引用方法
工作中,所有的tools里有一个project是只包含若干个schema的工程,研究了一下,发现创建这种只包含schema的dll其实非常简单. 首先,在visual studio-new proje ...
- 面试题:编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。(c++实现)
实例说明 示例 1: 输入: ["flower","flow","flight"] 输出: "fl" 示例 2: 输入: ...
随机推荐
- 学习记录--C++组合+依赖+依赖倒置
组合关系:表示类之间的关系是整体与部分的关系.即has a / contains a的关系 在面向对象程序设计中,将一个复杂对象分解为简单对象的组合. 在代码中,体现为将一个或多个类的对象作为另一个类 ...
- OSPF的收敛特性
- 布局管理器wx.BoxSizer
b = wx.BoxSizer( wx.VERTICAL ) b.Add(self.notebook1, 1, wx.EXPAND) self.parent.SetSizer(b) 解析以上代码原理, ...
- Windows10彻底关闭自动更新
此文操作流程只针对于Windows10 1803及以下版本,更新版本未测试. Windows10在本地组策略编辑器禁用了自动更新,系统依然会在某个时候触发自动更新,怎么办呢,方法来了. 这个方法是结合 ...
- 当transcational遇上synchronized
工作当中经常会遇到既需要开启事务管理,同时也需要同步保证线程安全的场景. 比如一个方法 @Transactional public synchronized void test(){ // } 不知道 ...
- 剑指offer 第 17 天
第 17 天 排序(中等) 剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3. ...
- 机器学习系列入门系列[七]:基于英雄联盟数据集的LightGBM的分类预测
1. 机器学习系列入门系列[七]:基于英雄联盟数据集的LightGBM的分类预测 1.1 LightGBM原理简介 LightGBM是2017年由微软推出的可扩展机器学习系统,是微软旗下DMKT的一个 ...
- Win11右键菜单改回传统样式
Win11右键菜单,比较不人性化,隐藏了一些常用选项,需要点"更多选项"才能显示,多次一举. 解决方法,一句话: reg.exe add "HKCU\Software\C ...
- 如何用java校验SQL语句的合法性?(提供五种解决方案)
方案一:使用JDBC API中提供的Statement接口的execute()方法 要在Java中校验SQL语句的合法性,可以使用JDBC API中提供的Statement接口的execute()方法 ...
- opengl helloworld vscode 通过glfw 绘制三角形
opengl helloworld vscode 调用glfw 绘制三角形 目录 opengl helloworld vscode 调用glfw 绘制三角形 打开 glfw.org, 我下的64 目录 ...