剑指 Offer II 005. 单词长度的最大乘积

这篇博客介绍了如何使用位运算高效地解决LeetCode中的一个问题——寻找字符串数组中不包含相同字符的字符串对的最大长度乘积。博主详细阐述了利用位运算判断字符串是否有相同字符的逻辑,并给出了具体的Java代码实现。算法中,位运算起到了关键作用,通过将字符映射为二进制并进行按位与操作,快速判断两字符串是否包含相同字符,从而找到最大乘积。
摘要由CSDN通过智能技术生成

题目

链接:https://leetcode.cn/problems/aseY1I/

给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。

img

思路

首先我们肯定是要遍历这个数组里的每个word了,双重遍历数组,保证每两个元素都能对比上。

重点的问题是:

  1. 如何判断两个字符串中有相同的字符。想要高效的处理,还是得用位运算。
  2. 找到最大值。

解法:位运算

逻辑

我们用位运算来解决判断两个字符串中是否有相同字符的问题。

将abcde……对应成数字01234。用一个26位长的二进制数字,来记录哪个字符出现过。

img

比如字符串abea和efgg对应的二进制值,以及二者做&运算后的值,如图所示:

img

因为有相同的字符,因此结果是大于0的。

所以我们的主要逻辑是:

  1. 遍历字符串数组,将每个字符串中字符出现的情况保存为二进制对应的数字,保存到一个整型数组中
  2. 使用一个变量缓存最大积。
  3. 再次遍历这个整形数组,通过&运算来判断是否存在相同数字。如果不存咋,则计算二者长度的积,和缓存的最大积比较,当前结果大则替换

代码

public int maxProduct(String[] words) {
    // 将每个字符串中字符出现的结果,保存到整型数组里
    int[] temp = new int[words.length];
    for (int i = 0; i < words.length; i++) {
        for (int j = 0; j < words[i].length(); j++) {
            // 使用|运算符将字符words[i].charAt(j)在二进制temp[i]的对应位置置为1
            temp[i] |= 1 << (words[i].charAt(j) - 'a');
        }
    }

    // 保存最大值
    int max = 0;
    for (int i = 0; i < temp.length; i++) {
        for (int j = i + 1; j < temp.length; j++) {
            // 使用&运算符对比第i个单词和第j个单词中是否有相同数字
            if ((temp[i] & temp[j]) == 0) {
                int multiplyResult = words[i].length() * words[j].length();
                max = Math.max(max, multiplyResult);
            }
        }

    }

    return max;
}

一些思考

算法题中,bitmap和位运算实在是太常用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白码上飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值