问题描述
我想问一个用户2个数字范围以生成第三个数字。 (这样做是为了根据市场趋势设置自定义售价。)
例如,在1到2之间,生成的数字是3。在2到3之间,它将是4.5 (此数字由用户固定,我们必须存储它)。
>然后,当我将要处理一些数据并且仅具有市场价格编号时,我将必须知道它在哪个编号范围内,并找到相应的生成编号。
我考虑过要存储3个数据:startingValue,endingValue和userValue。但这意味着我必须检索所有数据并每次浏览每个数字游侠,这会导致N的时空复杂度。
我不知何故可以在固定时间内完成。
你有什么主意吗?还是我做错了?
解决方法
我不认为您可以在固定时间内得到答案(我认为很难证明在经典复杂性假设下在固定时间内不可行)。
不过,您可以在(select distinct on (primary_key_col_1,primary_key_col_2) u.primary_key_col_1,u.primary_key_col_2,u.value_col_1,u.value_col_2
from updated u
order by primary_key_col_1,primary_key_col_2,primary_key_col_3 desc
) union all
select r.primary_key_col_1,r.primary_key_col_2,r.value_col_1,r.value_col_2
from raw r
where not exists (select 1
from updated u
where u.primary_key_col_1 = r.primary_key_col_2 and
u.primary_key_col_2 = r.primary_key_col_2
);
中找到答案,其中O(log n)
是必须存储的范围数。
您需要做的就是将范围存储在一个排序的数组中,如下所示:
假设您有两个范围n
和(a,b) -> v1
(您对注释的回答意味着这些范围是相邻的)。
然后,您可以使用元组(b,c) -> v2
的数组,并使用binary search查找相应的值。
由于m.raynal的回答,我可以在 log(n)时空复杂度方面做到这一点。范围相邻的事实使之成为可能。
它使用递归。
function findTheRightPriceRange(arrayOfPriceRanges,priceInput,counter = 0) {
if (
!Array.isArray(arrayOfPriceRanges) ||
(Array.isArray(arrayOfPriceRanges) && arrayOfPriceRanges).length === 0
) {
return -2;
}
counter++;
let middleArrayIndex = Math.floor(arrayOfPriceRanges.length / 2);
let currentPointer = arrayOfPriceRanges[middleArrayIndex];
if (priceInput >= currentPointer[0] && priceInput <= currentPointer[1]) {
return currentPointer[2];
}
if (priceInput <= currentPointer[0]) {
return findTheRightPriceRange(
arrayOfPriceRanges.splice(0,middleArrayIndex),counter
);
}
if (priceInput >= currentPointer[0]) {
return findTheRightPriceRange(
arrayOfPriceRanges.splice(
middleArrayIndex,arrayOfPriceRanges.length - 1
),counter
);
}
return -1;
}