以下是查找总计最多3对的程序。
例如:
输入:0,3,5,1,2,4
输出:0,3,1,2。
这意味着它应该返回总和等于3的所有对。
但我想减少这个程序的时间复杂度。现在我使用两个嵌套的for循环。
任何人都可以建议一种更好的方法来减少时间复杂度。
#include<iostream>
#include <vector>
using namespace std;
void main()
{
vector<int> v;
vector<int> r;
int x;
cout << "Enter the elements";
for(int i = 0; i < 6; i++)
{
cin >> x;
v.push_back(x);
}
for(int i = 0 ; i < v.size() - 1; i++)
{
for(int j = i + 1; j < v.size(); j++)
{
if(v[i] + v[j] == 3)
{
r.push_back(v[i]);
r.push_back(v[j]);
}
}
}
cout << "\noutput\n";
for(int i = 0 ; i < r.size(); i++)
{
cout<<r[i]<<"\n";
}
}
答案 0 :(得分:3)
我要做两个准备步骤;首先,消除所有数字&gt; 3,因为它们不会成为任何有效对的一部分。这降低了第二步的复杂性。其次,对剩余的数字进行排序,以便单次浏览可以找到所有结果。
遍历从排序数组的两端接近对;如果找到一对,则两个边界都可以缩小;如果当前结束总和达到>> 3,只有一个边界变窄。
运行时复杂性为O(N logN)
,其中N
是元素的数量&lt; = 3; O(N logN)
基本上来自排序;两个单独的漫游将不计入大N
s。
int main(int argc, char* argv[]) {
const int N = 3;
std::vector<int> input{ 0,3,5,1,2,4};
std::vector<int>v(input.size());
int t=0;
for (auto i : input) {
if (i <= N) {
v[t++]=i;
}
}
std::sort (v.begin(), v.end());
long minIdx = 0;
long maxIdx = v.size()-1;
while (minIdx < maxIdx) {
int minv = v[minIdx];
int maxv = v[maxIdx];
if (minv+maxv == 3) {
cout << minv << '+' << maxv << endl;
minIdx++;maxIdx--;
}
else
minIdx++;
}
return 0;
}
答案 1 :(得分:1)
您正在搜索 n 元素中两个数字之间的所有组合,更具体地说,是那些总结为特定值的数字。这是子集求和问题的变体。
为了实现这一点,您可以生成所有组合而不重复保存值的向量的索引。以下是如何执行此操作的示例recursively,此处是如何执行此操作的示例iteratively,只是为了获得一个想法并可能将其用作您案例中的基准。
另一种方法是dynamic programming和backtracking。
答案 2 :(得分:0)
我认为你可以用O(n)用地图来解决这个问题。
public void printPairs(int[] a, int v)
{
map<int, int> counts = new map<int, int>();
for(int i = 0; i < a.length; i++)
{
if(map.count(a[i]) == 0)
{
map[a[i]] = 1;
}
else
{
map[a[i]] = map[a[i]] + 1;
}
}
map<int, int>::iterator it = map.begin();
while(it != map.end())
{
int v1 = it->second;
if (map.count(v - v1) > 0)
{
// Found pair v, v1
//will be found twice (once for v and once for v1)
}
}
}
答案 3 :(得分:0)
延迟回答但适用于负整数 ...首先,找到std::vector<int>
中的最小数字,然后像this回答说的那样,删除所有元素(或复制相反的),高于3 + minimum
。在对std::vector<int>
进行排序后,从两端迭代它,条件如下所示:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
std::vector<int> findPairs(const std::vector<int>& input, const int sum) {
int minElem = INT_MAX;
for(auto lhs = input.begin(), rhs = input.end() - 1; lhs < rhs;
++lhs, --rhs) {
const int elem = (*lhs < *rhs ? *lhs : *rhs);
if(elem < minElem)
minElem = elem;
}
std::vector<int> temp(input.size());
const auto tempBegin = temp.begin();
const auto tempEnd = std::remove_copy_if(input.begin(), input.end(),
temp.begin(), [minElem, sum](int elem) {
return (elem + minElem) > sum;
});
std::sort(tempBegin, tempEnd);
std::vector<int> result;
auto leftIter = tempBegin;
auto rightIter = tempEnd - 1;
while(leftIter < rightIter) {
if(*leftIter + *rightIter == sum) {
result.push_back(*leftIter++);
result.push_back(*rightIter--);
}
else {
if(sum - *leftIter < *rightIter) rightIter--;
else leftIter++;
}
}
return result;
}
int main() {
auto pairs = findPairs({ 0, 3, 5, 1, 2, 4, 7, 0, 3, 2, -2, -4, -3 }, 3);
std::cout << "Pairs: { ";
for(auto it = pairs.begin(); it != pairs.end(); ++it)
std::cout << (it == pairs.begin() ? "" : ", ") << *it;
std::cout << " }" << std::endl;
}
上面的代码将产生以下结果:
Pairs: { -4, 7, -2, 5, 0, 3, 0, 3, 1, 2 }