我有一个功能,该功能可以检查是否有一个索引i
,使其等于v[i]
。 V
是严格升序的向量。它需要在O(logn)
中完成,我想到了划分。我从未真正熟悉过递归。我写了这段代码,但我真的不知道为什么它不起作用。缺少一些东西。如果我放cout << mid
而不是返回,它将显示正确的值,但是坦率地说,我认为这不是正确的方法。在此阶段,返回的中间值为7,我不知道为什么。
这是代码。
int customDivide(vector <int>& v, int left, int right)
{
if(left <= right)
{
int mid = (left+right)/2;
if(mid == v[mid]){
//cout<<mid<<" ";
return mid;
}
customDivide(v,left,mid-1);
customDivide(v,mid+1,right);
}
}
答案 0 :(得分:2)
这里存在两个问题,我将尝试用在您的邻居中找到失落狗的类比来解释它们。
除非您立即找到正确的元素,否则您不会从函数中返回值。您保证会返回一个值(一个int
),但并非总是如此。
这就像许诺给狗主人寄一封信,指出在哪里可以找到他们的失踪狗。您检查您的花园,如果找到狗,您就寄一封信-可以。如果找不到狗,请去找邻居,并让他们答应如果他们找到了狗,就用与您相同的方法(递归)向您发送一封信。问题在于,在这种情况下,您不是在阅读或转发其字母(最后两个递归函数调用的返回值)-您只是在扔掉这些字母 >。更糟糕的是,如果您自己找不到狗的话,您实际上并没有将这封信发回寻找他的狗的人(通话后没有return
)。您的代码似乎假设邻居会自动将信件发送给养狗人,而不是return
的工作方式,它只是将信件发送给链中的前一个人(在代码中为调用堆栈),因此如果该人立即将其扔进垃圾桶,则该系统将无法正常工作。
如果无条件递归双方,则无法获得O(log(n))性能。
如果您总是问所有的邻居(他们都问所有的邻居),那么您附近的每个人实际上都会在找狗。那是O(n)。您必须确定两个邻居中的哪个应该寻找狗(例如,通过观察狗左的踪迹),并且只问那个狗。这样一来,您将每一步搜索狗的人数减少了一半,从而为您带来O(log(n))的表现。
此“线索”是您需要事先知道的。在您的情况下,不清楚可能是什么-狗可能在任何地方(所有元素都可能具有随机值),并且您不知道去哪里寻找。您需要弄清楚此任务的详细信息才能达到O(log(n))时间。向量元素可能正在严格增加(请参阅@ Jarod42的评论),即没有重复的元素,并且每个元素都大于前一个元素。在这种情况下,您可以确定剩下的两半中只有一个可以包含您要查找的内容,从而在此重复。
(是的,除非您的邻居的形状像一棵二叉树,顶部位于您的顶部,并且“邻居”的定义互为倒数,否则类比会破裂。)
答案 1 :(得分:1)
作为这里所有帮助的结果,我终于了解了问题所在。
int customDivide(vector <int>& v, int left, int right)
{
if(left <= right)
{
int mid = (left+right)/2;
if(mid == v[mid])
return mid;
else if(v[mid] < mid)
return customDivide(v,mid+1,right);
else
return customDivide(v,left, mid-1);
}
return -1;
}
非常感谢您的帮助!