我有一个值向量,它在最小值之后不减,在最小值之前不增。这是一个例子:
std::vector<int> arr = {90, 80, 70, 60, 55, 62, 71, 89, 104}
在这个例子中,我想找到数字55。 我希望能够高效地找到它的最小值。 O(n)时间复杂度不够快。据说可以通过修改二分查找来解决,但我想知道是否存在其他解决方案。
我有一个值向量,它在最小值之后不减,在最小值之前不增。这是一个例子:
std::vector<int> arr = {90, 80, 70, 60, 55, 62, 71, 89, 104}
int findTurningPoint(const vector<int>& v, int begin, int end) {
int mid = (begin + end) / 2;
if (v[mid - 1] > v[mid] && v[mid + 1] > v[mid]) {
return mid;
} else if (v[mid - 1] > v[mid]) {
return findTurningPoint(v, mid + 1, end);
} else if (v[mid - 1] < v[mid]) {
return findTurningPoint(v, begin, mid - 1);
}
}
vector<int> arr = {90, 80, 70, 60, 55, 62, 71, 89, 104};
cout << findTurningPoint(arr, 0, arr.size() - 1); // 4
方法解释:
选择向量中间的元素。通过与它的邻居进行比较,检查其是否形成极小值。如果没有,则找出该元素及其邻居是否形成递增序列。如果是,则对中间元素左侧的所有元素重复上述过程。否则,重复该过程以对中间元素右侧的所有元素进行操作。
begin < end
和 v[mid] < v[mid+1]
)。您当前的实现可能会读取数组的两端,这也是一个问题。 - Ben Voigtbegin>=end
(更多迭代)。现在,每次迭代/递归最多有6个比较,而且你仍然没有处理基本情况(因为begin==end
可能从第一个调用就为真),所以至少有7个比较。将其减少到2或3可能是一种净胜利,即使没有早期退出,平均迭代/递归计数也会增加。 - Ben Voigt