我正在尝试设计一种算法来查找数组中两个相同元素的索引。输入是一个数组,输出是两个索引i和j,这样array [i] = array [j]。 时间复杂度必须为O(nlogn)。
这是我尝试过的
var body: some View {
NavigationView {
ScrollView(.horizontal) {
HStack {
ForEach(part.getReference()) { (imageRef: ReferenceImage) in
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage())) {
Image(uiImage: imageRef.getUIImage())
.resizable()
.frame(width: 90, height: 90)
.cornerRadius(6)
}
}
}
}
}
}
嵌套循环为O(n ^ 2),但是如果我尝试这样设计的话。时间的复杂度是多少?
n是数组的大小 我的实现将运行O(n [(n-1)+(n-2)+(n-3).... + 1])次。还是O(n ^ 2),有人告诉我是O(nlogn),为什么?
答案 0 :(得分:1)
您可以保留两个数组:一个带有值(A
),另一个带有索引(I
)。可能的O(nlogn)
算法可能是:
A
与索引数组I
并行排列。 (时间复杂度:O(nlogn)
)。A
并将每个元素与其右边的邻居进行比较,如果发现重复,则可以在I
中返回相应的索引。 (时间复杂度:O(n)
)我在python函数中实现了这个想法:
import operator
def repeatedNumber(A):
if len(A) <= 1:
return -1
# building the indices array
indices = range(len(A))
# join the two arrays
zipped = zip(A, indices)
# sort the arrays based on value
zipped = sorted(zipped, key=operator.itemgetter(0))
# scan the array and compare every pair of neighbor
for i in range(len(zipped)):
if zipped[i][0] == zipped[i + 1][0]:
return zipped[i][1], zipped[i+1][1]
return -1
您可以尝试一些示例:
A = [2,3,5,2,6]
,请给(0, 3)
A = [2, 3, 100, 6, 15, 40, 7, 3]
,请给(1, 7)
答案 1 :(得分:0)
您知道算法的时间复杂度为O(n^2)
。为了获得更好的结果,您可以先对数组进行排序,然后找到索引。
如果对数组进行排序,则具有相同值的两个索引可能会并排放置。因此,您可以遍历排序后的数组,并报告排序后的数组中两个当前邻居索引的原始索引。
排序的时间复杂度可能是O(n log n)
,然后遍历数组是O(n)
。因此,该算法为O(n log n)
。
答案 2 :(得分:0)
您可以使用地图进行反向查找
function findSame(theValues) {
var inverseLookup = {};
var theLength = theValues.length;
for (var i = 0; i < theLength; ++i) {
if (inverseLookup[theValues[i]] != undefined) {
return ([inverseLookup[theValues[i]], i]);
}
inverseLookup[theValues[i]] = i;
}
return [];
}
console.log(findSame([1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9]));
for
循环具有O(n)时间+ inverseLookup
具有O(1)时间+ O(n)空间(哈希表)