我遇到了这个问题,想知道是否有更好的解决方案。
例如
期望的输出 ==> [2,4]
编辑:再举一个例子
期望的输出 ==> [2,4]
到目前为止,我发现并尝试过的运行在O(nlogn)+ O(blogn)和O(n)中。
O(nlogn)+ O(blogn)方法:
int binarysearch(vector<int>arr, int l, int r, int target)
{
int mid;
while(l <= r)
{
mid = (r+l) / 2;
if(arr[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
return r;
}
vector<int> counts(vector<int> a, vector<int> b)
{
vector<int> result;
sort(a.begin(), a.end()); // O(nlogn)
for(auto i : b){
int count = binarysearch(a, 0, a.size()-1, b); // b*O(log n) times
result.push_back(count)
}
return result;
}
O(n)方法:
vector<int> counts(vector<int> a, vector<int> b)
{
vector<int> result;
int maxi = *max_element(b.begin(), b.end()) + 1;
int mymap[maxi] = {0};
for(auto i : a) mymap[i]++;
for(int i = 1; i < maxi; i++){
mymap[i] = mymap[i] + mymap[i-1];
}
for(auto i : b){
result.push_back(mymap[i]);
}
return result;
}
答案 0 :(得分:1)
[我]在想是否有更好的复杂度来解决问题。
时间复杂度。
O(n)方法:
不,没有比线性时间复杂度低的解决方案。
也就是说,您的线性解是错误的。如果输入数组包含1000000或更大的值或负数,则访问mymap
的边界之外,并且行为未定义。此外,i <= 1000000
还在上次迭代的边界之外访问mymap
。此外,int[1000000]
太大而不能成为局部变量。在某些系统上,即使是这样的变量也可能导致堆栈溢出。
答案 1 :(得分:1)
没有比O(n)
更好的方法了。
所以这也是O(n)
,但改编了STL样式:
template <class Iter1, class Iter2>
std::vector<std::size_t> counts(const Iter1 beg_a, const Iter1 end_a, const Iter2 beg_b, const Iter2 end_b)
{
std::vector<std::size_t> result;
const auto& max = *std::max_element(beg_b, end_b);
std::vector<std::size_t> mymap(max + 1, 0);
for (auto iter = beg_a; iter != end_a; iter++)
{
if (*iter <= max)
{
mymap[*iter]++;
}
}
for (std::size_t i = 1; i < mymap.size(); i++)
{
mymap[i] = mymap[i] + mymap[i - 1];
}
for (auto iter = beg_b; iter != end_b; iter++)
{
result.push_back(mymap[*iter]);
}
return result;
}
答案 2 :(得分:0)
好吧,事实证明,有一种更快的方法来计算地图索引。例如给定a = {1,4,2,4,5,8,80}和b = {3,1000000}。 所需输出为[2,7]。
使用我以前的方法,我需要计算mymap [4],mymap [5] .. mymap [9999] .... mymap [1000000]。这就是程序崩溃并返回运行时错误的原因。
我们处理此问题的方法是使用for(auto&entry:mymap),它可以访问所有字典/地图。然后,我们使用upper_bound STL C ++返回正确的映射。
vector<int> counts(vector<int> nums, vector<int> maxes){
vector<int> result;
map<int,unsigned int> mymap;
for(auto i : nums) mymap[i]++;
// doesn't need to run 1000000 times
int temp = 0;
for(auto& entry: mymap){
entry.second = entry.second + temp;
temp = entry.second;
//cout << "first : " << entry.first << "second: " << entry.second << endl;
}
map<int,unsigned int>::iterator itl;
for(auto i : maxes){
itl = --mymap.upper_bound(i); // points to the correct map
result.push_back(itl->second);
}
return result;
}
答案 3 :(得分:0)
首先让我们采用更好的表示法:让我们称A为a中元素的数量,B为B中元素的数量,并说元素为M位值。
正如其他人所说,您的解决方案是A log(A)
来构建映射,再加上B log(A)
来获取返回的值。
使用https://en.wikipedia.org/wiki/Y-fast_trie可以得到(A+B) log M
,如果使用A >> M
,则速度更快(但在大多数情况下,实践中可能会更慢)。
答案 4 :(得分:-1)
希望这对您有所帮助。
private List<Integer> compareAndCount (@NotNull List<Integer> integerListA, @NotNull List<Integer> integerListB){
List<Integer> countedIntList = new ArrayList<>();
int counter;
for (int B : integerListB ){
counter = 0;
for (int A : integerListA){
if(A < B){
counter++;
}
}
countedIntList.add(counter);
}
return countedIntList;
}