假设我在A = {a,b,c,d,e,f,g}
中有一个数组I={1,3,5}
和一组(从零开始)索引A
。现在假设我实际上没有A
,但只有I
中A
中指定的索引删除的数组,即B = {a,c,e,g}
(我本身也有I
。
鉴于B
中的索引,我可以在A
中分析计算相应的索引吗?例如,对于B
中的索引3,答案应为6。
很容易想到O(|A|)
解决方案,但由于A
可能会变得非常大,所以这是不可接受的。 O(|I|)
解决方案应该没问题。另请注意,I
可能会定期更改(删除了更多索引)。
答案 0 :(得分:0)
也许使用一个数组,B
中的每个元素都会在该索引被移除{0,1,2,3}
之前具有元素数,然后将索引转换为B
并查看在该数组中,将该值添加到B
的索引中,以使索引进入A
。这将占用额外的空间,等于B
的大小,但为O(1)
。
答案 1 :(得分:0)
" I"将原始数组拆分成一些切片。我们可以得到B连接这些切片。使用I={1,3,5}
我们得到切片{0, 0}, {2,2}, {4,4}, {6,lastA}
我们可以创建一个有序地图,其中键是B中的索引,值是切片。
{ 0: {0,0}, 1: {2, 2}, 2: {4, 4}, 3: {6,lastA} }
实际上,我们不需要保持每个切片的上限
{ 0: 0, 1: 2, 2: 4, 3: 6 }
在C ++代码中,make看起来像这样:
std::function<size_t (size_t)> getIndexConverter(size_t sizeOfA, std::vector<size_t> I)
{
std::map<size_t, size_t> abIndices;
size_t sliceStart = 0;
for (size_t i = 0, imax = I.size(); i < imax; ++i) {
if (sliceStart < I[i])
abIndices.emplace(sliceStart - i, sliceStart);
sliceStart = I[i] + 1;
}
if (sliceStart < sizeOfA)
abIndices.emplace(sliceStart - I.size(), sliceStart);
return [abIndices](size_t bIndex) -> size_t {
auto slice = abIndices.lower_bound(bIndex);
assert(slice != abIndices.end()); // it is impossible because of algorithm we use to construct abIndices
return bIndex - slice->first + slice->second;
};
}
此方法需要额外的内存等于切片数量,并以对数时间执行。