面试问题。我正在寻找一种比O(n ^ 2)更好的算法,其中n是输入数组的大小。 (N< 5000)
问题陈述如下:
假设我们得到一个正整数数组(让我们称之为a)。找出一种方法来重新排列这些元素的顺序,以便可以最大化以下函数的值:
obj = a [0] * a [1] + a [1] * a [2] + ... + a [n-2] * a [n-1] + a [n- 1] * A [n]的
此外,还有一个布尔数组(让我们称之为b),它与正整数数组的大小完全相同。如果b [k] = false,则意味着当我们在正数组中重新排列元素时,我们无法移动第k个元素。
示例
a = [1,2,3],b = [true,true,true]
由于b的所有元素都是真的,我们可以根据我们所知道的重新排列数组。有六种方法可以重新排列它(例如[1,2,3],[1,3,2],[2,1,3] ....)。以下是这六种安排的目标函数值。最大化目标函数的安排是[1,3,2]或[2,3,1],因为:
1 * 3 + 3 * 2 = 9
2 * 3 + 3 * 1 = 9
另一个例子:
a = [1,2,3],b = [true,false,true]
在这种情况下,整数2不能移动,因此只有两个排列 - [1,2,3]和[3,2,1]。它们都产生相同的目标函数值。
更新
我使用强力方法测试@ shapiro.yaacov在具有不同元素的正整数数组上提供的算法。这是我运行的一些测试:
输入:[1,2,4,8,16,32,64]
输出:
obj = 3412,当[2,8,22,64,16,4,1]或
obj = 3412,当[1,4,16,64,32,8,2]
时输入:[1,10,100,1000]
输出:
obj = 110100,当[1,100,1000,10]或
时obj = 110100,当[10,1000,100,1]
时正如您所看到的,至少有两种安排可以最大化目标函数 - 一种安排是另一种安排的反转版本。
即使这不是这个问题的要求,这个算法也适用于那些带0的数组。但是,我们需要在没有零的情况下提出最佳排列,然后将0添加到新排列的任一侧。例如:
输入:[0,1,2,4,8,16,32,64]
输出:
obj = 3412,当[2,8,32,64,16,4,1,0]或
obj = 3412,当[0,2,8,32,64,16,4,1]或
obj = 3412,当[1,4,16,64,32,8,2,0]或
时obj = 3412,当[0,1,4,16,64,32,8,2]
答案 0 :(得分:0)
这是$("#formId").on("submit", function(e){
e.preventDefault();
$.ajax({
method: "POST",
url: "some.aspx",
data: { name: "John", location: "Boston" }
}).done(function(data) {
if(data check)
$("#formId").submit();
});
});
的解决方案:
获取数组O(n*logn)
,并对其中的所有(可能)元素进行排序。可能我的意思是那些b数组中的索引是真的。此步骤需要a
。
<强>推荐使用:强>
给定 obj 函数,您希望将最大数字乘以第二大数字,将第二个数字与第三个数字相乘等。可以通过交换具有最小数字的O(n*logn)
来完成某些优化,然后a [1]将是最大的等等(a[0]
obj 更大)。在任何情况下,由于您已经对数组进行了排序,因此这一步很简单a = [1, 2, 3, 4, 8]
。
修改强>
鉴于 obj 功能,以及与@Edward Doolittle的对话后,这可能是最好的安排:
O(n)
编辑2:
处理无法移动的元素:首先排序可以排序的元素。然后查看它们可以去的位置,并通过两侧的乘数对位置进行排序。因此,如果一个可选位置一侧有8个而另一侧有3个,则乘数的值为24.然后将最高值元素分配给最高值位置。
现在无法证明这是最佳的,但它并非遥远。我想。