该算法取自LeetCode:https://leetcode.com/problems/maximum-product-of-word-lengths/description/
这是我创建的jsperf(我有一些本地测试可以得到相同的结果):https://jsperf.com/maximum-product-of-word-lengths
这是第一个"慢"实现:
function maxProduct (words) {
if (!words || !words.length) return 0;
let len = words.length;
let values = [];
// console.log(values)
for (let i = 0; i < len; ++i) {
let tmp = words[i];
let num = 0, len = tmp.length;
for (let j = 0; j < len; ++j) {
num |= 1 << (tmp.charCodeAt(j) - 'a'.charCodeAt(0));
}
values[i] = {
num: num,
len: tmp.length
};
}
let maxProduct = 0;
for (let i = 0; i < len; ++i) {
for (let j = 0; j < len; ++j) {
if ((values[i].num & values[j].num) == 0) {
maxProduct = Math.max(maxProduct, values[i].len * values[j].len);
}
}
}
return maxProduct;
};
这是&#34;快速&#34;实现:
function maxProductFast (words) {
var temp = [];
for(var i = 0; i < words.length; i++){
var tempObj = {};
tempObj.item = words[i];
var num = 0;
for(var j = 0; j < words[i].length; j++){
num |= 1 << (words[i].charCodeAt(j) - 97);
}
tempObj.num = num;
temp.push(tempObj);
}
var res = 0;
for(var i = 0; i < temp.length; i++){
for(var j = i + 1; j < temp.length; j++){
var item1 = temp[i];
var item2 = temp[j];
if((item1.num & item2.num) == 0) {
res = Math.max(res, item1.item.length * item2.item.length);
}
}
}
return res;
}
答案 0 :(得分:1)
他们不一样。第二算法具有复杂度为(n *(n + 1))/ 2的循环,其中每个渐进步骤从i + 1到temp的长度。第一个算法有两个嵌套的for循环,每个循环的成本为n ^ 2。两者的复杂性将降低到O(n ^ 2)。我相信这两种方法都具有相似的性能和足够大的设置。
你为每次子迭代做n + 1的原因是因为你试图找到任何一对项目的最大值。如果将元素放在网格中,您会注意到任何对角线对a_3 * a_2 = a_2 * a_3都会产生相同的值。你基本上可以将收集减半并节省几个周期。