当前位置:网站首页>leetcode/单词长度的最大乘积
leetcode/单词长度的最大乘积
2022-07-28 06:33:00 【xcrj】
代码
package com.xcrj;
import java.util.HashMap;
import java.util.Map;
/** * 剑指 Offer II 005. 单词长度的最大乘积 * 给定一个字符串数组words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。 */
public class Solution5 {
/** * 蛮力法,遍历 */
public int maxProduct1(String[] words) {
int maxLen = 0;
for (int i = 0; i < words.length; i++) {
String wordi = words[i];
// j=i: word0和word1比较过了,word1和word0不用再比较
for (int j = i; j < words.length; j++) {
String wordj = words[j];
if (!hasSameChar1(wordi, wordj)) {
maxLen = Math.max(maxLen, wordi.length() * wordj.length());
}
}
}
return maxLen;
}
/** * wordj.indexOf(c) * 有1个相同字符就返回true */
public boolean hasSameChar1(String wordi, String wordj) {
for (char c : wordi.toCharArray()) {
// 只有有1个相同字符则返回true
if (-1 != wordj.indexOf(c)) return true;
}
return false;
}
/** * 字母 数组散列表统计 */
public int maxProduct2(String[] words) {
int maxLen = 0;
for (int i = 0; i < words.length; i++) {
String wordi = words[i];
// j=i: word0和word1比较过了,word1和word0不用再比较
for (int j = i; j < words.length; j++) {
String wordj = words[j];
if (!hasSameChar2(wordi, wordj)) {
maxLen = Math.max(maxLen, wordi.length() * wordj.length());
}
}
}
return maxLen;
}
/** * 数组散列表:将不同字母散列到闭散列表的不同位置 * 散列函数:idx=c-'a' */
public boolean hasSameChar2(String wordi, String wordj) {
// 26个字母,26个空间的散列表
int[] counts = new int[26];
// 将wordi中每个字母放入counts数组中的不同位置
for (char c : wordi.toCharArray()) {
int idx = c - 'a';
counts[idx] = 1;
}
// 将wordj中每个字母放入counts数组中的不同位置
for (char c : wordj.toCharArray()) {
int idx = c - 'a';
// idx散列位置处已经有值了,证明存在相同字母
if (1 == counts[idx]) {
return true;
}
}
return false;
}
/** * 字母 位散列表统计 */
public int maxProduct3(String[] words) {
int maxLen = 0;
for (int i = 0; i < words.length; i++) {
String wordi = words[i];
// j=i: word0和word1比较过了,word1和word0不用再比较
for (int j = i; j < words.length; j++) {
String wordj = words[j];
if (!hasSameChar3(wordi, wordj)) {
maxLen = Math.max(maxLen, wordi.length() * wordj.length());
}
}
}
return maxLen;
}
/** * 位散列统计 * 散列函数:bitMask=1<<c-'a' */
public boolean hasSameChar3(String wordi, String wordj) {
// 构建32bit闭散列表
int bitMask1 = 0;
int bitMask2 = 0;
for (char c : wordi.toCharArray()) bitMask1 |= 1 << c - 'a';
for (char c : wordj.toCharArray()) bitMask2 |= 1 << c - 'a';
// 如果没有相同的字符则&结果为0;
return 0 == (bitMask1 & bitMask2) ? false : true;
}
/** * 取得每个单词位散列表示,存储到bitMasks[]中 */
public int maxProduct4(String[] words) {
// 存储每个单词的位散列表示
int[] bitMasks = new int[words.length];
for (int i = 0; i < words.length; i++) {
String word = words[i];
int bitMask = 0;
for (char c : word.toCharArray()) bitMask |= 1 << c - 'a';
bitMasks[i] = bitMask;
}
// 寻找没有相同位的单词
int maxLen = 0;
for (int i = 0; i < bitMasks.length; i++) {
int bitMaski = bitMasks[i];
String wordi = words[i];
for (int j = i; j < bitMasks.length; j++) {
int bitMaskj = bitMasks[j];
String wordj = words[j];
if (0 == (bitMaski & bitMaskj)) {
maxLen = Math.max(maxLen, wordi.length() * wordj.length());
}
}
}
return maxLen;
}
/** * hashMap统计优化maxProduct4 * Map<bitMask,Len> */
public int maxProduct5(String[] words) {
// 存储每个单词的位散列表示
Map<Integer, Integer> maskLenMap = new HashMap<>();
for (int i = 0; i < words.length; i++) {
String word = words[i];
int bitMask = 0;
for (char c : word.toCharArray()) bitMask |= 1 << c - 'a';
// ab aabb单词的bitMask一致,取aabb的最大长度
maskLenMap.put(bitMask, Math.max(maskLenMap.getOrDefault(bitMask, 0), word.length()));
}
// 找出没有相同字符的单词
int maxLen = 0;
for (int ki : maskLenMap.keySet()) {
for (int kj : maskLenMap.keySet()) {
// 不含有相同字符
if (0 == (ki & kj)) {
maxLen = Math.max(maxLen, maskLenMap.get(ki) * maskLenMap.get(kj));
}
}
}
return maxLen;
}
public static void main(String[] args) {
Solution5 solution5 = new Solution5();
System.out.println(solution5.maxProduct5(new String[]{
"abcw", "baz", "foo", "bar", "fxyz", "abcdef"}));
}
}
参考
作者:tangweiqun
链接:https://leetcode.cn/problems/aseY1I/solution/jian-dan-yi-dong-javac-pythonjs-zui-da-d-ffga/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
边栏推荐
- Detailed explanation of random number generated by random class
- 记录一次mycat连接Communications link failure问题解决
- Common solutions for distributed ID - take one
- Technology sharing | common proxy tools for interface testing
- What if the task manager is not fully displayed?
- Es6: template string
- MySQL query error [err] 1046 - no database selected
- 单片机IO口控制12V电压通断,MOS和三极管电路
- Can a flinksql script write insert statements for two tables?
- Redis of non relational database [jedis client +jedis connection cluster]
猜你喜欢

Use ffmpeg to generate single image + single audio streaming video in batches

【13】 Adder: how to build a circuit like Lego (Part 1)?

One key switch circuit
![[Qt5] QT small software release](/img/83/9867bd4513caadac6a056c801abe48.png)
[Qt5] QT small software release

Understand CDN

MCU IO port controls 12V voltage on and off, MOS and triode circuit

Prescan quick start to master the road elements of lecture 15

记录一次mycat连接Communications link failure问题解决

Melt cloud x chat, create a "stress free social" habitat with sound

【活动报名】云原生技术交流 Meetup,8 月 6 日广州见
随机推荐
Qt多线程中槽函数在哪个线程里执行分析
Enum class
JS candy xiaoxiaole game source code
"Wei Lai Cup" 2022 Niuke summer multi school training camp 2 supplementary question record (dghjkl)
Use ffmpeg to generate single image + single audio streaming video in batches
Prescan quick start to master the transportation elements in lesson 14, prescan
OpenTSDB-时序数据库
Mechanical revolution Jiaolong P wired network card driver can't play
How do we run batch mode in MySQL?
pyflink连接iceberg 实践
Mysql, how can we get the number of rows affected by the query?
Unity中队列(Queue)的简单使用
Oracle local network service
[book club issue 13] Chapter 1 multimedia processing tools ffmpeg tools
Exception handling in SQL Server
豪华版h5俄罗斯方块小游戏源码
What if the computer file cannot be deleted?
How to build the protection system of class protection technology of 2022 series of ISO compliance (Part I)
五张图看懂EMI电磁干扰的传播过程-方波陡峭程度对高频成分的影响,时序到频域频谱图形,波形形状对EMI辐射的影响。
Pytorch的冻结以及解冻