我们假设我们有一个数组a
= {...},我们应该回答一些查询,每个查询包含2个索引l
和r
,每个查询的答案为YES
或NO
:
是:如果子阵列[l,r]的所有元素都不存在于数组的其余部分(段[1,l-1]和段[r + 1,n])。< / p>
否:否则
我能得到的最好的东西是o(n ^ 3)解决方案:迭代每个段(i,j),取O(n ^ 2),然后为每个段检查该段的所有元素,使它&#39 ;总体而言是O(n ^ 3)。
我至少需要O(n ^ 2)解决方案或一些提示,谢谢。
例如:a = [4,4,2,5,2,3] 查询:
1 2 - &gt;是
3 5 - &gt;是
2 3 - &gt; NO
4 6 - &gt; NO
答案 0 :(得分:2)
预处理:遍历数组并创建每个元素的散列映射counts
,以计算它在数组中出现的频率。
对于每个查询:遍历子数组并创建一个散列映射queryCounts
来存储每个元素的计数。在queryCounts
中查找counts
的每个元素并比较计数 - 返回&#34;是&#34;如果所有的计数都匹配,&#34; no&#34;否则。
运行时间:预计 O(n)预处理和每次查询O(n)。
<强>的伪代码:强>
(假设当您尝试访问时,地图中不存在的元素将初始化为0,类似于C ++&#39; std::map
)
预处理:
array[n] // the input array
Map<int -> int> counts
for i = 1 to n
counts[array[i]]++
对于查询i j
:
Map<int -> int> queryCounts
for x = i to j
queryCounts[array[x]]++
for each key y in queryCounts
if queryCounts[y] != counts[y]
return "no"
return "yes"
示例:强>
数组:[4, 4, 2, 5, 2, 3]
hashmap将是:
2 -> 2
3 -> 1
4 -> 2
5 -> 1
如果在子阵列[2,5]上有查询3 4
(从1开始),我们会得到:
2 -> 1
5 -> 1
我们将其与第一个hashmap进行比较,看看2
的计数是否匹配,因此我们返回&#34; no&#34;。
替代方法:
您还可以在预处理期间循环遍历所有子阵列并存储您是否返回&#34;是&#34;或&#34;不&#34;得到 O(n 2 )预处理和每个查询的O(1)。
请注意[i,j]
的散列图可以通过在[i,j-1]
的计数中加1来从array[j]
的散列图中获取,因此我们只需要执行O(1 )如果我们跟踪错误计数的数量,并且仅检查更改array[j]
的计数将如何更改此数字,则在预处理期间每个子阵列的工作。
<强>的伪代码:强>
预处理:
array[n] // the input array
Map<(int, int) -> String> queryResults
for i = 1 to n
Map<int -> int> queryCounts // clear on every i iteration
countsWrong = 0
for j = i to n
if queryCounts[array[j]] == counts[array[j]]
countsWrong++ // the counts match, the below operation will make it not match
queryCounts[array[j]]++
if queryCounts[array[j]] == counts[array[j]]
countsWrong--
if countsWrong == 0
queryResults[i,j] = "yes"
else
queryResults[i,j] = "no"
对于查询i j
:
return queryResults[i,j]
示例:强>
数组:[4, 4, 2]
hashmap将是:
2 -> 1
4 -> 2
我们从i=1, j=1
开始:
4 -> 1
countsWrong = 1 // since 4's count is wrong (not 2)
queryResults[1,1] = "no"
对于i=1, j=2
,我们添加1到4的计数:
4 -> 2
countsWrong = 0 // 4's count is now right
queryResults[1,2] = "yes"
对于i=1, j=3
,我们添加1到2的计数:
4 -> 2
2 -> 1
countsWrong = 1 // 2's count is right
queryResults[1,3] = "yes"
对于i=2, j=2
,我们重置地图和1到4的计数:
4 -> 1
countsWrong = 1 // 4's count is wrong (not 2)
queryResults[2,2] = "no"
对于i=2, j=3
,我们添加1到2的计数:
4 -> 1
2 -> 1
countsWrong = 1 // 2's count is right, 4's is wrong (not 2)
queryResults[2,3] = "no"
对于i=3, j=3
,我们会重置地图和1到2的计数:
2 -> 1
countsWrong = 0 // 2's count is right
queryResults[1,2] = "yes"