• LeetCode - 318 最大单词长度乘积(Java & JS & Py & C)


    目录

    题目来源

    题目描述

    示例

    提示

    题目解析

    算法源码


    题目来源

    318. 最大单词长度乘积 - 力扣(LeetCode)

    题目描述

    给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。

    示例

    输入:words = ["abcw","baz","foo","bar","xtfn","abcdef"]
    输出:16 
    解释:这两个单词为 "abcw", "xtfn"。

    输入:words = ["a","ab","abc","d","cd","bcd","abcd"]
    输出:4 
    解释:这两个单词为 "ab", "cd"。

    输入:words = ["a","aa","aaa","aaaa"]
    输出:0 
    解释:不存在这样的两个单词。

    提示

    • 2 <= words.length <= 1000
    • 1 <= words[i].length <= 1000
    • words[i] 仅包含小写字母

    题目解析

    本题首先需要遍历出两个单词words[i]和words[j],之后如果将这两个单词逐字符比较的话,则肯定会超时。

    一种优化策略是,将单词按照一定规则转化为二进制数,规则如下:

    每个单词中的字母,都可以转化为相较于字母'a'的ASCII码偏移量,比如:

    • 字母'b' 相较于 'a' 的偏移量是1
    • 字母'c' 相较于 'a' 的偏移量是2

    如果我们将这些偏移量想象为二进制数的位,那么一个单词就可以转化为一个二进制数,比如:

    单词"abc",其中 'a' 的偏移量是0,'b'的偏移量是1, 'c'的偏移量是2

    则可得二进制数 0000 0111

    具体实现如下:

    1. // 单词对应的二进制数
    2. bit = 0
    3. // 遍历单词word的每一个字母letter
    4. for (letter in word) {
    5. // 计算字母的偏移量
    6. offset = ascii(letter) - ascii('a')
    7. // 按位或
    8. bit |= 1 << offset
    9. }

    上面按位或的运算,是为了将各个字母的偏移量都归纳到一个二进制数中。

    按位或的特点是:操作数中只要有一个为1,则结果为1,

    因此一个单词中出现重复字母也没事,因此1 | 1 = 1,利用此特点还可起到去重作用。

    经过上面逻辑,我们就将单词转化为二进制数。

    接下来单词之间比较是否存在相同字母,就可以转化为比较两个二进制数是否存在都为1的位。

    而按位与&运算的特点是:

    • 两个操作数都为1,结果才为1,即 1 & 1 = 1,
    • 有一个操作数为0,则结果为0,即 1 & 0 = 0,0 & 1 = 0

    因此只要将两个单词对应二进制数进行按位与&运算,结果只要为0,则说明两个二进制数不存在同时为1的位,即两个单词不存在相同字母。

    Java算法源码

    1. class Solution {
    2. public int maxProduct(String[] words) {
    3. int ans = 0;
    4. int n = words.length;
    5. int[] bits = new int[n];
    6. for(int i=0; i
    7. for(int j=0; j
    8. bits[i] |= 1 << (words[i].charAt(j) - 'a');
    9. }
    10. }
    11. for(int i=0; i
    12. for(int j=i+1; j
    13. if((bits[i] & bits[j]) == 0) {
    14. ans = Math.max(ans, words[i].length() * words[j].length());
    15. }
    16. }
    17. }
    18. return ans;
    19. }
    20. }

    JS算法源码

    1. /**
    2. * @param {string[]} words
    3. * @return {number}
    4. */
    5. var maxProduct = function (words) {
    6. let ans = 0;
    7. const n = words.length;
    8. const bits = new Array(n).fill(0);
    9. for (let i = 0; i < n; i++) {
    10. for (let j = 0; j < words[i].length; j++) {
    11. bits[i] |= 1 << (words[i][j].charCodeAt() - 97);
    12. }
    13. }
    14. for (let i = 0; i < n; i++) {
    15. for (let j = i + 1; j < n; j++) {
    16. if ((bits[i] & bits[j]) == 0) {
    17. ans = Math.max(ans, words[i].length * words[j].length);
    18. }
    19. }
    20. }
    21. return ans;
    22. };

    Python算法源码

    1. class Solution(object):
    2. def maxProduct(self, words):
    3. """
    4. :type words: List[str]
    5. :rtype: int
    6. """
    7. ans = 0
    8. n = len(words)
    9. bits = [0]*n
    10. for i in range(n):
    11. for j in range(len(words[i])):
    12. bits[i] |= 1 << (ord(words[i][j]) - 97)
    13. for i in range(n):
    14. for j in range(i+1, n):
    15. if (bits[i] & bits[j]) == 0:
    16. ans = max(ans, len(words[i]) * len(words[j]))
    17. return ans

    C算法源码

    1. #define MAX(a,b) (a) > (b) ? (a) : (b)
    2. int maxProduct(char ** words, int wordsSize){
    3. int ans = 0;
    4. int* bits = (int*) calloc(wordsSize, sizeof(int));
    5. for(int i=0; i
    6. for(int j=0; j<strlen(words[i]); j++) {
    7. bits[i] |= 1 << (words[i][j] - 'a');
    8. }
    9. }
    10. for(int i=0; i
    11. for(int j=i+1; j
    12. if((bits[i] & bits[j]) == 0) {
    13. ans = MAX(ans, strlen(words[i]) * strlen(words[j]));
    14. }
    15. }
    16. }
    17. return ans;
    18. }
  • 相关阅读:
    计算机的组成部件的作用
    基于纳芯微产品的尾灯方案介绍
    【EI会议征稿】第七届电子器件与机械工程国际学术会议(ICEDME 2024)
    软考 系统架构设计师系列知识点之特定领域软件体系结构DSSA(4)
    配置HBase和zookeeper
    开机自启动Linux and windows
    数据挖掘与机器学习:循环结构
    SpringMVC工作原理
    每日一题:LeetCode-589.N叉树的前序遍历
    PHP:类常量
  • 原文地址:https://blog.csdn.net/qfc_128220/article/details/133788623