我想找到一种算法来计算阵列中不同子阵列的数量。
例如,在 A = [1,2,1,2] 的情况下,不同子数组的数量为 7:
{ [1] , [2] , [1,2] , [2,1] , [1,2,1] , [2,1,2], [1,2,1,2]}
在B=[1,1,1]的情况下,不同子阵列的数量为3:
{ [1] , [1,1] , [1,1,1] }
子数组是数组的连续子序列或片段。不同意味着内容不同;例如:
来自A[0:1]的[1]和来自A[2:3]的[1]不是不同的。
类似地:
B[0:1],B[1:2],B[2:3]并不明显。
您可以简单地制作一组子序列并对其进行计数,但我不确定这是最有效的方法,因为它是O(n^2)
。
在python中,这将是这样的:
subs = [tuple(A[i:j]) for i in range(0, len(A)) for j in range(i + 1, len(A) + 1)]
uniqSubs = set(subs)
这给了你:
set([(1, 2), (1, 2, 1), (1,), (1, 2, 1, 2), (2,), (2, 1), (2, 1, 2)])
理解中的双循环清楚地说明了O(n²)
的复杂性。
显然,有一些关于复杂性的讨论。子项的创建是 O(n^2
),因为有 n^2
项。
从列表创建集合是 O(m),
其中 m
是列表的大小,在本例中 m
为 n^2
,因为添加到集合中是摊销 O(1)。
因此,整体为O(n^2)。
编辑:我想到如何减少迭代/比较次数。我有一种方法可以做到这一点:如果你检索一个大小为n的子数组,那么每个大小小于n的子html" target="_blank">数组都将被添加。
下面是更新后的代码。
List<Integer> A = new ArrayList<Integer>();
A.add(1);
A.add(2);
A.add(1);
A.add(2);
System.out.println("global list to study: " + A);
//global list
List<List<Integer>> listOfUniqueList = new ArrayList<List<Integer>>();
// iterate on 1st position in list, start at 0
for (int initialPos=0; initialPos<A.size(); initialPos++) {
// iterate on liste size, start on full list and then decrease size
for (int currentListSize=A.size()-initialPos; currentListSize>0; currentListSize--) {
//initialize current list.
List<Integer> currentList = new ArrayList<Integer>();
// iterate on each (corresponding) int of global list
for ( int i = 0; i<currentListSize; i++) {
currentList.add(A.get(initialPos+i));
}
// insure unicity
if (!listOfUniqueList.contains(currentList)){
listOfUniqueList.add(currentList);
} else {
continue;
}
}
}
System.out.println("list retrieved: " + listOfUniqueList);
System.out.println("size of list retrieved: " + listOfUniqueList.size());
要研究的全球列表: [1, 2, 1, 2]
检索到的列表:[[1,2,1,2],[1,2,1],[1,2],[2,1,2],[2,1,2],[2,1],[2]]
检索到的列表大小:7
如果一个列表多次包含相同的patern,那么迭代和比较的次数将非常少。对于您的示例[1,2,1,2],如果(!listOfUniqueList.contains(电流列表)){行被执行10次。对于包含15个不同子数组的输入[1,2,1,2,1,2],它只上升到36。
为此数组构建后缀树。然后把这棵树所有边的长度加在一起。
构造后缀树所需的时间是O(n)与正确的算法(Ukkonen的或McCreight的算法)。遍历树并将长度相加所需的时间也是O(n)。
我最近在一次编码面试中遇到了这个问题。问题如下: 给定一个包含n个数字和k个数字的数组A[],计算不同子数组的总数,使得每个子数组最多包含k个奇数元素。 我使用DP方法来解决问题,但我的解决方案没有照顾到部分。 我的解决方案在O(nk)时空内有效。 我该如何处理差异性?有没有解决这个问题的数学公式? 编辑: 例如1: 例如2: 例如 3:
有人能为下面的问题提出一个简单的解决方案吗? 最长子数组:查找子数组中元素之和小于或等于“k”的最长连续子数组的长度。 输入为:< code>array和< code>k。 例子: 输出: 2个 解释: 子数组:{1},{2},}3},1,2},2,3},{1,2,3} {1,2} =
你有一个整数数组。您必须找到子阵列的数量,该数量意味着(这些元素的总和除以这些元素的计数)舍入为零。我已经用O(n^2)时间解决了这个问题,但效率不够。有办法吗?
给定一个(未排序的)数组S和一些整数k,找到对的数量i, j使得S的范围[i... j] 我在一次采访中收到了这个问题,经过排序后只能得出一个O(nlogn)解。但是,有人告诉我有一个O(n)解。有什么想法吗?
我在一次面试中有以下问题,尽管我给出了一个可工作的实现,但它不够高效。 数组A的切片是任何一对整数(P,Q),使得0≤ P≤ Q 我被要求编写的函数必须返回可被K整除的切片数。预期的时间复杂度为O(max(N, K)),空间复杂度为O(K)。 我的解决方案是最简单的,一个循环套一个循环,检查每一个切片:O(n^2) 我一直在想,但我真的不知道如何在O(max(N, K))中做到这一点。 它可能是子
我在一次采访中遇到了以下问题。 给定一个数组,您需要找到所有元素小于给定值 k 的子数组 ,例如 现在,值小于 4 的子数组是: 注意{4}是如何重复的,但没有考虑两次。现在,代码应该返回不同子阵列的计数 在本例中为3. 另一个示例: 不同的子阵列: 我的方法是找到小于给定值k(即O(n^2))的子阵列,然后将其插入类似无序集的内容中以删除重复项。 有没有解决这个问题的有效方法?