Javascript 有人能解释为什么这不起作用吗?
我正在进行面试。这基本上是自己布置的作业。我做了几次尝试,我的解决方案相当难看,但我不明白为什么它不能给我正确的输出。在算法中只执行一个循环,我尝试过切换顺序,以及沿着这条路线的其他版本 我有点被困在这里,有两个关于这个算法的问题,我正试图用直接的Javascript来完成 问题是: 您有一个整数数组,对于每个索引,您希望找到除该索引处的整数外的每个整数的乘积。编写一个函数get_products_of_all_ints_,但_at_index()除外,该函数接受一个整数数组并返回一个乘积数组。不要使用除法 数组[1,7,3,4] 将返回: [84,12,28,21] 通过计算: [7*3*4,1*3*4,1*7*4,1*7*3] 我过度劳累的尝试如下:Javascript 有人能解释为什么这不起作用吗?,javascript,algorithm,Javascript,Algorithm,我正在进行面试。这基本上是自己布置的作业。我做了几次尝试,我的解决方案相当难看,但我不明白为什么它不能给我正确的输出。在算法中只执行一个循环,我尝试过切换顺序,以及沿着这条路线的其他版本 我有点被困在这里,有两个关于这个算法的问题,我正试图用直接的Javascript来完成 问题是: 您有一个整数数组,对于每个索引,您希望找到除该索引处的整数外的每个整数的乘积。编写一个函数get_products_of_all_ints_,但_at_index()除外,该函数接受一个整数数组并返回一个乘积数组。
var l = [84, 12, 28, 21],
products_before_curr_index = 1,
products_after_curr_index = 1,
backwards_index=1,
forwards_index,
product_array = [];
for(var factor=0; factor<l.length; factor++){
forwards_index=factor+1;
while(forwards_index<l.length){
products_after_curr_index*=l[forwards_index];
forwards_index+=1;
}
if(factor>0){
products_before_curr_index *= l[factor-backwards_index];
backwards_index+=1;
}
product_array.push(products_after_curr_index*products_before_curr_index);
backwards_index=1;
products_after_curr_index = 1;
products_before_curr_index=1;
}
var l=[84,12,28,21],
当前索引之前的产品=1,
当前指数=1后的产品,
指数=1,
远期指数,
乘积_数组=[];
对于(var factor=0;factor是的,看起来有点过于复杂了。问题描述为您提供了一点解决问题的提示。对于数组中的每个整数,您希望找到所有其他整数的乘积。换句话说,您可以循环数组中的每个项,然后再次循环数组中的每个项(aka,嵌套循环)并将除第一个数组的当前索引之外的所有乘积相加
例如:
var a = [1, 7, 3, 4];
var b = [];
a.forEach(function( value_1 ) {
var product = 1;
a.forEach(function( value_2 ) {
if ( value_1 != value_2 )
product *= value_2;
});
b.push( product );
});
console.log( b ); // [84, 12, 28, 21]
您的原始解决方案不起作用,因为您只返回一次。您使用while循环向前遍历整个数组以计算所有元素的乘积,但您只使用一次计算来向后:
products_before_curr_index *= l[factor-backwards_index];
因此,您只能得到当前索引之前的值的乘积。您再也不会返回。如果您想知道,您只会碰巧得到第三个值(28
),因为第一个数字是1
(也就是说,乘以1
)不会有任何作用)。尝试将第一个数字更改为任何不是1
的数字,您将看到第三个计算也会失败。这一个使用数组对象的map和reduce方法
function get_products_of_all_ints_except_at_index(inList) {
var product = function (x, y) { return x * y; };
var lists = inList.map(function (v, i, a) {
return a.slice(0, i).concat(a.slice(i + 1, a.length));
});
return lists.map(function (v, i, a) { return v.reduce(product); });
}
// test case
console.log(get_products_of_all_ints_except_at_index([1, 7, 3, 4]));
我并不特别喜欢面试蛋糕给出的解决方案,我觉得它很复杂。我可能没有最优化的解决方案,我使用了Numpy,它不清楚我们是否可以(但它没有说我们不能,所以…)
它适用于所有测试用例,我觉得它更简单/更容易掌握:
`将numpy作为np导入
def get_products_of_all_ints_except_at_index(int_list):
if len(int_list) < 2:
raise IndexError("you need two numbers at least")
products = []
for i in range(len(int_list)):
temp_list = int_list.copy()
del temp_list[i]
prod = np.prod(temp_list)
products.append(prod)
return products
def get_products_of_all_ints_,除了索引处的(int_list):
如果len(内部列表)<2:
raise INDEXROR(“您至少需要两个数字”)
产品=[]
对于范围内的i(len(int_列表)):
temp_list=int_list.copy()
删除临时清单[i]
产品=np.产品(临时清单)
产品。附加(产品)
退货
我认为问题的关键是找到一个O(n)解决方案。@Teepeemm如果问题是找到一个O(n)解决方案,那么问题描述应该说明这一点。我和大多数其他堆栈溢出用户都不是读心术的人。如果问题描述没有说“我正在寻找一个O(n)解决方案”显然,我不会写一个O(n)解:)这不是“O(n)解。只有slice
是O(1)时,这才是O(n)。@Teepeemm是的,你是对的。John Resig的Array.remove方法使用一个片和一个推,而不是上面提到的两个片和一个concat,效率更高。[]再看一遍,每个reduce
都将是O(n),你这样做n
次,所以整个算法必须是O(n^2)上面的方法。这可能已经在别处被问到和回答过了,但我没有时间找到它。1.制作一个prefix
数组,其中I
th条目是I
之前所有内容的乘积:prefix[I+1]=prefix[I]*array[I]
.2.通过另一个方向通过数组
制作一个后缀
数组。3.找到每个术语的成对乘积。我找到了一个这样的例子。我没有看到使用切片或映射的O(n)方法。