假设我们有一个数组{7,3,7,3,1,3,4,1}。 我需要的是一种算法(最好是一些C ++代码示例),该算法将返回包含该数组所有元素的最小子数组的长度。
在这种情况下,它将是5:{7,3,1,3,4},这是原始数组的最短子数组,其中包含该数组的所有元素,即1,3,4和7.
另外,数组{2,1,1,3,2,1,1,1,3}的另一个示例,该算法应返回3,因为我们正在寻找的子数组是{1,3,2}(原始数组的索引2-4)。
我在这里找到了类似的问题:Find minimum length of sub-list containing all elements of a list 但似乎没有答案。
函数签名应类似于:
int algorithm(std::vector<int> &arr){...}
答案 0 :(得分:2)
查找O(n)中的最后一个子数组:
例如,对于数组[1, 2, 3, 2, 2, 1, 1]
,获取哈希表/ Map(或小范围数组)中项目的计数:{ 1: 3, 2: 3, 3: 1 }
要查找子数组的起始索引,请从数组中的第一个值开始,然后检查其计数是否大于1。如果计数大于1,则将其计数减一,然后继续下一个值直到一个计数值为1的值。向后重复相同的操作,以找到子数组的最后一个索引:
1, 2, 3, 2, 2, 1, 1
^ ^
找到O(n)中的其余子数组:
现在要检查这是否是最小子数组,请在此之前检查子数组。为此,请在第一个索引之前搜索值1的最后一个索引,该值位于最后一个索引处。如果找到它,则将第一个索引更改为它,然后将最后一个索引减少一个:
1, 2, 3, 2, 2, 1, 1
^ ^
现在要查找新子数组的最后一个索引,在第一个索引和最后一个索引之间搜索最后一个索引处的值2并将最后一个索引更改为它:
1, 2, 3, 2, 2, 1, 1
^ ^
重复直到在第一个索引和最后一个索引之间找不到最后一个索引的值为止:
1, 2, 3, 2, 2, 1, 1
^ ^
现在检查新子数组的计数是否小于先前子数组的计数,并在需要时更新当前最小子数组的索引。
必须重复搜索其余子数组,直到在第一个索引之前找不到最后一个索引的值为止。