检查数组子数组的所有元素是否都不存在于数组的其余部分

时间:2017-05-28 13:32:57

标签: arrays algorithm

我们假设我们有一个数组a = {...},我们应该回答一些查询,每个查询包含2个索引lr,每个查询的答案为YESNO

是:如果子阵列[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

1 个答案:

答案 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"