【发布时间】:2021-10-22 03:38:13
【问题描述】:
我正在尝试解决 BinarySearch.com 上的问题:
给定一个按升序排序的整数列表 nums 和一个整数 k,返回列表中任意两个元素加起来是否为 k。您不能两次使用相同的元素。注意:数字可以是负数或 0。这应该在
O(1)空格中完成。
所以对于nums = [1, 3, 5, 8]和k = 6,答案应该是true。
我知道可以使用两个指针来完成,但是我正在学习二进制搜索,所以我想出了以下逻辑:
bool solve(vector<int>& nums, int k) {
for(int i=0; i<nums.size(); i++) {
auto loc=lower_bound(begin(nums), end(nums), k-nums[i]);
if(loc!=nums.end()) {
if(distance(nums.begin(), loc)!=i && *loc+nums[i]==k) return true;
}
}
return false;
}
它被接受了,但是时间复杂度是多少?我不确定它是否是O(NlogN),因为我对nums 中的每个值运行二进制搜索(O(logN) 算法),或者它是否应该是O(N^2),因为当if 条件为真时,我使用distance(),据我了解,它本身就是一个 O(n) 操作。
【问题讨论】:
-
@Someone:对于 std::vector,
std::distance是一个常数时间操作。 -
@AndyG,很酷,谢谢!
-
改进:
*loc+nums[i]==k总是正确的,因为您刚刚通过搜索找到了*loc == k - nums[i]。您也不需要搜索整个向量;从begin(nums) + i + 1开始。这也将使您的其他条件变得不必要。 -
@YvesDaoust,抱歉打错了。我的意思是:“我运行二进制搜索(一个 O(logN) 算法)N 次)。
-
@molbdnilo:改进这个版本没有什么意义,因为你可以在没有任何二分搜索的情况下解决问题。
标签: c++ algorithm time-complexity binary-search