使用循环在具有重复项的旋转排序数组中查找枢轴点。尽管我在建议中找到了解决方案,但这是使用递归的。我需要使用递归的解决方案。从最近的12小时开始,我就一直困扰着这个问题。任何帮助将不胜感激。
直到现在,我一直尝试找到单元格,该单元格周围的两个元素都大于元素本身。但是它似乎没有用。谁能告诉我我要去哪里错了。
int findPivot(vector<int>& nums)
{
int lo=0,hi=nums.size()-1,mid,n=nums.size();
while(lo<=hi)
{
mid = (lo+hi)>>1;
if(nums[(mid+1)%n] >= nums[mid] && nums[(mid-1+n)%n]>nums[mid])
return mid;
if(nums[mid]>nums[hi])
lo = mid+1;
else
hi = mid-1;
}
return 0;
}
但是对于这样的情况,[3,1]似乎不起作用,我得到0,预期输出为1和[1,1,3,1] 3我得到0。
答案 0 :(得分:0)
问题在这里:
if(nums[mid] > nums[hi])
您不能安全地使用此条件,将其修改为使用>=
或与nums[lo]
组合使用,将其更改为<
或<=
都无济于事;考虑以下两个序列:
{ 1, 1, 1, 2, 1 }
{ 1, 2, 1, 1, 1 }
0 2 4
lo mid hi
使用lo
或hi
的 any 组合与上述任何一个比较器,由于选择了不良的一半,两个序列之一将被错误地评估!您在序列{ 1, 1, 3, 1 }
中遇到了这种情况。
因此,如果您遇到这种情况(nums[x]
,lo
和hi
都相等),则必须检查一半!我认为最容易实现两个递归调用。请注意,如果三个索引中的任何值不同,则无需递归。 如果您需要递归,则仅对于两个子结果之一,实际后继项会较小,因此该结果将是最终结果。
您可以检测到e。 G。如下:
mid
假设您已将该功能转换为带有签名的递归功能
if(nums[mid] > nums[hi] || nums[mid > nums[lo])
{
hi = mid - 1;
}
else if(nums[mid] < nums[lo] || nums[mid] < nums[high]
{
lo = mid + 1;
}
else
{
int idxLo = findPivotRecursively(nums, lo, mid - 1);
int idxHi = findPivotRecursively(nums, mid + 1, high);
return nums[idxHi] > nums[(idxHi + 1) % n] ? idxHi : idxLo;
}
对数组进行排序时,最后一个条件仅对int findPivotRecursively(std::vector const& nums, int high, int low);
或idxLo
中的一个为真;如果所有元素都相等({idxHigh
将选择最后一个),那么我选择的测试将导致选择向量的第一个元素。
助手功能将提供公共接口:
nums[idxLo] > nums[(idxLo + 1] ? /*...*/;
借助lambda,您可以完全隐藏工作功能。不幸的是,递归lambda不受直接支持,因此您将依靠this answer中所示的小技巧:
int findPivot(std::vector const& nums)
{
return findPivotRecursively(nums, 0, nums.size() - 1);
}