实施例 排序位置矢量[4,5,9,30,31,32,34,40,47] 区间长度= 6
我想在任何给定的长度为6的间隔内找到最大值。在上面提到的例子中,间隔将是 [数组值 - 数组值+间隔长度:此数组中存在的#Values]
答案应该是30-36,因为它的最大值是4。任何人对如何最佳地找到它有任何好的想法吗?
答案 0 :(得分:0)
我不知道如何在O(n.k)时间内完成此操作,其中n是数组中的项目数,k是“间隔长度”。
我考虑过对数组进行预处理以获得间隔值矩阵,但这会与基本的朴素算法具有相同的复杂性。
答案 1 :(得分:0)
这是我能想到的最快的方式。另外,注意:您将间隔定义为6,但随后表示它包含项目30到36(即7项),所以我基于此编写此代码:
int GetInterval(const vector<int> &sortedList, int intervalLength)
{
int lowest = sortedList[0];
int highest = sortedList[sortedList.size()-1];
vector<int> intervals(highest-lowest-intervalLength+1, 0);
int max = 0;
for(int i = 0; i < sortedList.size(); i++)
{
int base = sortedList[i] - lowest;
for(int j = -intervalLength; j <= intervalLength; j++)
{
int index = i + j + base;
if(index < 0 || index >= intervals.size()) continue;
if(++intervals[index] > intervals[max]) max = index;
}
}
return max + lowest;
}
所以,我实际上没有运行它,但它应该工作。它的大O是排序列表的长度乘以间隔长度。如果你将区间长度作为常数,则它是O(n)。希望这对你有用。另外,我希望c ++也适合你。
*注意它会返回间隔中的最小数字。
答案 2 :(得分:0)
反向扫描列表以消除一些回溯。
size_t find_interval(const std::vector& _positions, int _interval)
{
assert(_positions.size() >= 2);
size_t start_of_run = 0;
size_t end_of_run;
size_t idx;
size_t run_length = 0;
end_of_run = _positions.size() - 1;
idx = end_of_run - 1;
for(; idx >= 0; --idx)
{
if((_positions[end_of_run] - _positions[idx]) <= _interval)
{
// idx is still in the interval, see if it's the longest
// run so far
if((end_of_run - idx) > run_length)
{
start_of_run = idx;
run_length = end_of_run - idx;
}
}
else
{
// idx is out of the interval, so move end_of_run down to
// make a new valid interval
do
{
--end_of_run;
} while((_positions[end_of_run] - _positions[idx]) > _interval);
// we don't care about a run smaller than run_length, so move
// idx to the shortest interesting run
idx = end_of_run - run_length;
}
}
return start_of_run;
}
使用end_of_run
和idx
之间的二进制搜索可以更有效地更新end_of_run
变量,但这会使算法更难理解。