spoj ARRAYSUB:O(n)复杂性方法
spoj ARRAYSUB: O(n) Complexity Approach
我试图在spoj上解决这个问题http://spoj.pl/problems/ARRAYSUB
我用两种方法解决了这个问题
首先使用优化的暴力。第二,在k、2k、3k等处取枢轴并找到最大值。
尽管两种解决方案在最坏情况下都被接受,但复杂性为O(n*k);
有人能为这些问题提出O(n)解决方案吗
以下是我的最坏情况复杂度O(n*k)的运行接受代码:
#include<iostream>
#include<cstdio>
#include<climits>
using namespace std;
main()
{
long n;
cin >> n;
long *arr = new long[n];
for( long i=0;i<n;i++)
cin >> arr[i];
long k;
cin >> k;
long max=arr[0];
for(long i=1;i<k;i++)
{
if(arr[i]>max)
max=arr[i];
}
if(k!=n)
cout<<max<<" ";
else cout<<max;
for( long i=k;i<n;i++)
{
if(arr[i-k]==max)
{max=-1;
for(int j=i-k+1;j<=i;j++)
if(arr[j]>max)
max=arr[j];
if(i!=n)
cout<<max<<" ";
else cout<<max;
}
else{
if(arr[i]>max)
{ max=arr[i];
if(i!=n)
cout<<max<<" ";
else
cout<<max;
}
else
{
if(i!=n)
cout<<max<<" ";
else cout<<max;}
}
}
cout<<endl;
return(0);
}
在O(n)时间内用于解决此问题的数据结构是"deque"
大多数人认为,一种自然的方法是尽量保持队列大小与窗口大小相同。试着摆脱这种想法,试着跳出框框思考。删除冗余元素并只存储队列中需要考虑的元素是实现以下高效O(n)解决方案的关键。
void maxInWindow(vector<int> &A, int n, int k, vector<int> &B) {
deque<int> Q;
for (int i = 0; i < k; i++) {
while (!Q.empty() && A[i] >= A[Q.back()])
Q.pop_back();
Q.push_back(i);
}
for (int i = k; i < n; i++) {
B[i-k] = A[Q.front()];
while (!Q.empty() && A[i] >= A[Q.back()])
Q.pop_back();
while (!Q.empty() && Q.front() <= i-k)
Q.pop_front();
Q.push_back(i);
}
B[n-k] = A[Q.front()];
//B stores the maximum of every contiguous sub-array of size k
}
说明:
第一个for循环计算前'k'个元素的最大值,并将索引存储在Q.front()。这将变为B[0]=A[index]。在下一节中,如果A[i]大于之前存储的最大值,我们从后面推并弹出。如果索引的值小于i-k,则我们从前面弹出,这意味着它不再相关。
一种比Brute Force更有效的方法是使用红黑树(RB)作为数据结构。因为RB树具有在O(log n)时间中插入、移除和查找最小值或最大值的属性,其中n是树中的节点数。
尽管AVL树具有相同的属性,但与RB树相比,隐藏在Big O后面的常量很大。
该问题的总体复杂性现在将变为O(n lg k)。
首先在RB树中插入k个节点,然后使用find max来获得max元素。(2*log k)其次,我们移除插入的第一个元素,然后插入一个新元素,然后查询max元素。(3*log k)。按照同样的程序,我们大约需要(3*n*log k)。这就是O(n*logk)。
目前天真的暴力解决方案没有被接受,但这个解决方案被接受了。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- ByteSize() 方法的复杂性
- 此插入方法的时间和空间复杂性
- 方法向量的新/分配的复杂性::p ush_back
- spoj ARRAYSUB:O(n)复杂性方法
- 从高效方法中删除指定的字符(时间和空间复杂性)