C++ 找出数组中哪两个值使给定表达式最大化?
我遇到了一个非常简单的面试问题,但我的答案是错误的。有什么帮助吗?1) 我的解决方案中有任何错误吗?2) 时间复杂度O(n)有什么好主意吗 问题: 给定一个int数组C++ 找出数组中哪两个值使给定表达式最大化?,c++,algorithm,C++,Algorithm,我遇到了一个非常简单的面试问题,但我的答案是错误的。有什么帮助吗?1) 我的解决方案中有任何错误吗?2) 时间复杂度O(n)有什么好主意吗 问题: 给定一个int数组A[],定义X=A[i]+A[j]+(j-i),j>=i。查找X的最大值 我的解决办法是: int解决方案(向量&A){ if(A.empty()) 返回-1; 长-长最大偏差=-2000000000,当前偏差; int size=A.size(); 对于(inti=0;i我将使用伪代码编写,因为我没有太多时间,但这应该是使用递归的
A[]
,定义X=A[i]+A[j]+(j-i),j>=i
。查找X的最大值
我的解决办法是:
int解决方案(向量&A){
if(A.empty())
返回-1;
长-长最大偏差=-2000000000,当前偏差;
int size=A.size();
对于(inti=0;i我将使用伪代码编写,因为我没有太多时间,但这应该是使用递归的最有效的方法
compare(array, left, right)
val = array[left] + array[right] + (right - left);
if (right - left) > 1
val1 = compare(array, left, right-1);
val2 = compare(array, left+1, right);
val = Max(Max(val1,val2),val);
end if
return val
而不是你简单的称呼
compare(array,0,array.length);
我想我找到了一个速度非常快的解决方案,但您需要检查它:
您需要按如下方式重写数组
Array[i] = array[i] + (MOD((array.lenght / 2) - i));
然后你只需找到数组中最高的2个值并求和,这应该是你的解,几乎是O(n)
等等,也许我遗漏了什么…我得检查一下
好的,从这个新数组中得到2个最大值,并保存位置i和j。然后需要从原始数组计算结果
------------编辑
这应该是我测试的Tony D(在c#中)建议的方法的实现
int best_i, best_j, max_i, currentMax;
best_i = 0;
best_j = 0;
max_i = 0;
currentMax = 0;
for (int n = 0; n < array.Count; n++)
{
if (array[n] - n > array[max_i] - max_i) max_i = n;
if (array[n] + array[max_i] - (n - max_i) > currentMax)
{
best_i = max_i;
best_j = n;
currentMax = array[n] + array[max_i] - (n - max_i);
}
}
return currentMax;
int-best_i,best_j,max_i,currentMax;
最佳_i=0;
最佳_j=0;
max_i=0;
currentMax=0;
for(int n=0;n数组[max\u i]-max\u i)max\u i=n;
if(数组[n]+数组[max_i]-(n-max_i)>currentMax)
{
最佳值=最大值;
最佳_j=n;
currentMax=array[n]+array[max_i]-(n-max_i);
}
}
返回电流最大值;
关键的洞察是,只有在确定潜在有用值是否可用之前跟踪它们的位置,才能在O(n)中完成
从best_i=best_j=max_i=0开始。前两个跟踪要在解决方案中使用的i和j值。下一个将记录i的影响因子最高的索引,即A[i]-i
最高
对于i和j的一些值,我们将X的值称为“Xi,j”,并从记录到目前为止我们的最佳解开始,ala Xbest=X0,0
沿阵列增加n
- 每当
[n]
处的值为a[i]-i
提供比max\u i更好的“i”贡献时,更新max\u i
- 当使用
n
作为“j”指数时,产生的Xmax\u i,n大于Xbest,best\u i=max\u i,best\u j=n
讨论-为什么/如何工作
j_random_hacker的评论建议我起草一份证据,但老实说,我不知道从哪里开始。我会尽力解释——如果其他人有更好的解释,请插手
重新解决问题:最大的席席,j在j >= i。给定我们可以设置X0,0的初始xBoST,问题是知道什么时候更新它,以及什么。当我们考虑数组中的连续索引作为j的潜在值时,我们想要为一些i生成Xi,j= n(下一步讨论)。与Xbest比较。但是,要使用什么i值?好吧,如果我们从已经访问过的索引中选择最佳i值,那么给定从0到n的任何索引is=i约束是不相关的。我们通过将与i相关的X贡献与与与j相关的贡献分开来计算出最佳i值-
A[i]-i
-因此,在考虑是否有一个新的、具有j=n的最佳解决方案时,我们必须同时保持最佳变量
解决问题的方法
不管它值多少钱——当我四处寻找解决方案时,我在纸上写下了一些想象中的I和j贡献,我可以看到这些贡献涵盖了有趣的案例……其中Ci和Cj是与n分别用作I和j有关的贡献,比如
n 0 1 2 3 4
Ci 4 2 8 3 1
Cj 12 4 3 5 9
你会注意到,当Cj是[j]时,我没有费心挑选Ci可以是[I]-I的值+j…我可以看到新出现的解决方案应该适用于任何公式,这会使捕获有趣的情况变得更加困难。那么-有趣的情况是什么?当n=2时,Ci值比我们在早期元素中看到的任何值都高,但仅考虑到这些早期元素的知识,我们还看不到使用它的方法。that场景是问题的一个“重大”复杂因素。需要的是Cj值至少为9,这样Xbest就会得到改进,这在n=4时正好出现。如果我们在[3]中找到更好的Ci然后我们当然想使用它。best_我跟踪等待一个足够好的Cj值索引的位置。我的评论的较长版本:从两端迭代数组,试图找到最大的数字,同时将其与适当的一端的距离减小。这会找到正确的索引(从而找到正确的X)吗?
#包括
#包括
#包括
#包括
#包括
long long残暴(const std::vector&a){
长x=LLONG_MIN;
对于(int i=0;i std::cout如果X
的最大值低于-2000000000
,该怎么办?只是一个想法(未测试):迭代数组怎么样
n 0 1 2 3 4
Ci 4 2 8 3 1
Cj 12 4 3 5 9
#include <vector>
#include <algorithm>
#include <iostream>
#include <random>
#include <climits>
long long brutal(const std::vector<int>& a) {
long long x = LLONG_MIN;
for(int i=0; i < a.size(); i++)
for(int j=i; j < a.size(); j++)
x = std::max(x, (long long)a[i] + a[j] + j-i);
return x;
}
long long smart(const std::vector<int>& a) {
if(a.size() == 0) return LLONG_MIN;
long long x = LLONG_MIN, y = x;
for(int i = 0; i < a.size(); i++)
x = std::max(x, (long long)a[i]-i);
for(int j = 0; j < a.size(); j++)
y = std::max(y, (long long)a[j]+j);
return x + y;
}
int main() {
std::random_device rd;
std::uniform_int_distribution<int> rlen(0, 1000);
std::uniform_int_distribution<int> rnum(INT_MIN,INT_MAX);
std::vector<int> v;
for(int loop = 0; loop < 10000; loop++) {
v.resize(rlen(rd));
for(int i = 0; i < v.size(); i++)
v[i] = rnum(rd);
if(brutal(v) != smart(v)) {
std::cout << "bad" << std::endl;
return -1;
}
}
std::cout << "good" << std::endl;
}