博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法-Hash/BitSet-字母异位词分组
阅读量:2181 次
发布时间:2019-05-01

本文共 2877 字,大约阅读时间需要 9 分钟。

算法-Hash/BitSet-字母异位词分组

1 题目概述

1.1 题目出处

https://leetcode-cn.com/problems/group-anagrams/

1.2 题目描述

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]

输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

说明:

  • 所有输入均为小写字母。
  • 不考虑答案输出的顺序。

2 BitSet-针对单词内无重复字符

2.1 思路

  1. 利用BitSet,记录所有字母是否出现,出现则那一个bit为1
  2. 仅适用于输入字符串都为字母且单词内无重复字母的情况。对于单词内有重复字母的,暂时没有想到利用BitSet来解决的方式。

2.2 代码

class Solution {
public List
> groupAnagrams(String[] strs) {
List
> resultList = new ArrayList<>(); if(strs == null || strs.length == 0){
return resultList; } if(strs.length == 1){
List
sList = new ArrayList<>(); sList.add(strs[0]); resultList.add(sList); return resultList; } Map
> longMap = new HashMap<>(); List
nullList = new ArrayList<>(); for(String str : strs){ if(str.length() == 0){ nullList.add(str); continue; } BitSet bitset = new BitSet(); char[] cs = str.toCharArray(); for(char c : cs){ bitset.set(c - 64); } long[] longs = bitset.toLongArray(); List
sList = longMap.get(longs[0]); if(sList == null){ sList = new ArrayList
(); longMap.put(longs[0], sList); resultList.add(sList); } sList.add(str); } if(nullList.size() > 0){ resultList.add(nullList); } return resultList; }}

2.3 时间复杂度

O(N*K)

  • 其中N为字符串数组strs长度,K为最长字符串长度

2.4 空间复杂度

O(N*K)

  • 其中N为字符串数组strs长度,K为最长字符串长度

3 整数分解为素数法则

3.1 思路

  1. 利用整数分解为素数法则,即每个整数都可以被分解为唯一组合的一堆素数的乘积。
  2. 所以每个单词,都可以拆分成单独字符后,将小写字符对应的Ascii码-'a'得到的数字下标对应的素数的乘积
  3. 但是该方法不适合单词过长,否则可能乘积溢出

3.2 代码

class Solution {
public List
> groupAnagrams(String[] strs) {
List
> resultList = new ArrayList<>(); if(strs == null || strs.length == 0){
return resultList; } if(strs.length == 1){
List
sList = new ArrayList<>(); sList.add(strs[0]); resultList.add(sList); return resultList; } Map
> longMap = new HashMap<>(); List
nullList = new ArrayList<>(); int[] primes = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101}; for(String str : strs){ if(str.length() == 0){ nullList.add(str); continue; } char[] cs = str.toCharArray(); long product = 1L; for(char c : cs){ product = product * primes[(c - 'a')]; } List
sList = longMap.get(product); if(sList == null){ sList = new ArrayList
(); longMap.put(product, sList); resultList.add(sList); } sList.add(str); } if(nullList.size() > 0){ resultList.add(nullList); } return resultList; }}

3.3 时间复杂度

在这里插入图片描述

O(N*K)

  • 其中N为字符串数组strs长度,K为最长字符串长度

3.4 空间复杂度

O(N*K)

  • 其中N为字符串数组strs长度,K为最长字符串长度

4 排序字符串

将每个单词先排序,然后跟HashMap中记录比对。

这种方法时间复杂度为O(N*K*logK),空间复杂度依然是O(N*K)

5 使用分隔符

将字符串中每个字符串统计,并使用分隔符做HashMap的Key。如:abbc,则转换后为a1#b2#c1

转载地址:http://wmpkb.baihongyu.com/

你可能感兴趣的文章
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>