LeetCode 318. Maximum Product of Word Length 解题报告

LeetCode 413. Arithmetic Slices 解题报告

题目描述

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.


示例

Example 1:

Given [“abcw”, “baz”, “foo”, “bar”, “xtfn”, “abcdef”]
Return 16
The two words can be “abcw”, “xtfn”.

Example 2:

Given [“a”, “ab”, “abc”, “d”, “cd”, “bcd”, “abcd”]
Return 4
The two words can be “ab”, “cd”.

Example 3:

Given [“a”, “aa”, “aaa”, “aaaa”]
Return 0
No such pair of words.


限制条件

没有明确给出.


解题思路

我的思路:

分成两步来解决:
1.处理所有字符串,记录它们包含的所有字母信息
2.两两比较所有的字符串的字母信息,如果均不相同并且长度积比当前的长度积要大,就更新长度积。最后返回长度积。

实现的时候就是用一个vector保存字符串的字母信息,比较字符串就是用之前解题时的方式,设一个大小为26的数组,扫描两个字符信息去更新这个数组,根据扫描结果得到比较结果,最后就是两个循环,进行两两比较并更新长度积。

然而,通过是通过了,但是时间却是很感人,仅比3%的通过代码快,几乎垫底了。。。所以还是看看大牛们的解法吧。

参考思路

核心思路就是我上面的两步,然而实现上却是有很多绝妙的技巧。
1.字符的字母信息用一个整型数表示,整型数的0-25bit对应着a-z,如果存在a,那么该整型数的第0bit就是1,这是通过位操作运算实现:对于1移动字符c - a个位置,然后与当前字母信息进行或运算。
2.设置一个unordered_map保存字符串的字母信息及长度,因此当存[aa],[aaaa]这类字母信息相同但是长度不同的字符串时,只有最长的长度会保存在unordered_map中,从而减少了比较的次数。
3.比较是在unordered_map中进行,而不是原始的字符串数组,通过相与两个字符串对应的字母信息,结果为1表明存在相同字母,为0则是没有相同字母,在为0时更新长度积。
最后返回长度积即可。


代码

我的代码

class Solution {
public:
    int maxProduct(vector<string>& words) {
        int product = 0;
        vector<string> unique(words.size());
        string letters = "abcdefghijklmnopqrstuvwxyz";

        for (int i = 0; i < words.size(); i++) {
            for (int j = 0; j < 26; j++) {
                if (words[i].find_first_of(letters[j]) != string::npos)
                    unique[i] += letters[j];
            }
        }

        for (int i = words.size() - 1; i > 0; i--)
            for (int j = i - 1; j >= 0; j--)
                if (!hasCommon(unique[i], unique[j]))
                    product = max(product, (int)(words[i].size() * words[j].size()));

        return product;
    }

    bool hasCommon(string s1, string s2) {
        int count[26] = {0};

        for (auto c: s1)
            count[c - 'a']++;

        for (auto c: s2) {
            if (count[c- 'a'])
                return true;
        }
        return false;
    }
};

参考代码

class Solution {
public:
    int maxProduct(vector<string>& words) {
        unordered_map<int, int> maxlen;
        int result = 0;

        for (string word: words) {
            int mask = 0;
            for (char c: word) 
                mask |= 1 << (c - 'a');
            maxlen[mask] = max(maxlen[mask], (int) word.size());
        }

        for (auto a: maxlen) {
            for (auto b: maxlen) {
                if (!(a.first & b.first))
                    result = max(result, a.second * b.second);
            }
        }

        return result;
    }
};

总结

这道题不难,然而要实现出高效的解法却不容易,我的解法是最最平庸的,所以不可取,从大牛们的解法中,我又学到了字符串的字母信息不仅可以用一个大小为26的数组表示,更可以直接通过位运算用整型数表示,真是好厉害!!!!然后unorder_map的使用也是很巧妙,佩服得不行,从这道题学习到了很多东西,超级开心点的,(^__^) 嘻嘻……。
又填好了一个坑,精彩明天继续!加油加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值