我有一个算法可以找到O(log n)
中两个大型排序数组的中位数但是如何返回给出中位数的中间两个数字,同时复杂度?例如:给定array1 = [1, 2, 3, 4, 50, 62, 77]
和array2 = [ 17, 27, 33, 89, 600, 700, 900]
,应返回33,50。
我找到中位数的代码:我无法将其修改为仅返回中位数。
class FindMedianSortedArrays {
func findMedian(input: [Int], startIndex: Int, endINdex: Int) -> Double {
let indexDifference = (endINdex - startIndex)
if indexDifference % 2 == 0 {
return Double(input[startIndex + (indexDifference/2)])
} else {
return Double(input[startIndex + (indexDifference/2)] + input[startIndex + (indexDifference/2) + 1])/2.0
}
}
func findMedianInSortedArray(inputA: [Int], inputB: [Int], startIndexA: Int, endIndexA: Int, startIndexB: Int, endIndexB: Int) -> Double {
var startIndexA = startIndexA
var endIndexA = endIndexA
var startIndexB = startIndexB
var endIndexB = endIndexB
if ((endIndexA - startIndexA) < 0) || ((endIndexB - startIndexB) < 0) {
print("Invalid Input")
}
if (endIndexA - startIndexA == 0) && (endIndexB - startIndexB == 0) {
return Double(inputA[0] + inputB[0])/2.0
}
if endIndexA - startIndexA == 1 && endIndexB - startIndexB == 1 {
return Double(max(inputA[startIndexA], inputB[startIndexB]) + min(inputA[endIndexA], inputB[endIndexB]))/2.0
}
let medianA: Double = findMedian(input: inputA, startIndex: startIndexA, endINdex: endIndexA)
let medianB: Double = findMedian(input: inputB, startIndex: startIndexB, endINdex: endIndexB)
//our second base case
if medianB == medianA {
return medianB //return either medianA or medianB
}
//since medianA <= median <= medianB,
//eliminate elements less than medianA and greater than medB
if medianA < medianB {
if((endIndexA - startIndexA) % 2 == 0) {
startIndexA = startIndexA + (endIndexA - startIndexA)/2
endIndexB = startIndexB + (endIndexB - startIndexB)/2
} else {
startIndexA = startIndexA + (endIndexA - startIndexA) / 2
endIndexB = startIndexB + (endIndexB - startIndexB) / 2 + 1
}
}
//since medianB <= median <= medianA, eliminate elements less
//than medianB and greater than medianA to narrow down the search.
else {
if ((endIndexB - startIndexB) % 2 == 0) {
startIndexB = startIndexB + (endIndexB - startIndexB)/2
endIndexA = startIndexA + (endIndexA - startIndexA) / 2 + 1
}
}
return findMedianInSortedArray(inputA:inputA, inputB: inputB, startIndexA: startIndexA, endIndexA:endIndexA, startIndexB: startIndexB, endIndexB: endIndexB)
}
}
答案 0 :(得分:1)
//: Playground - noun: a place where people can play
import Foundation
class FindMiddleNumbersInSortedArray {
func findMedianInSortedArray(inputA: [Int], inputB: [Int], startIndexA: Int, endIndexA: Int, startIndexB: Int, endIndexB: Int) -> [Int] {
var medianNumbers:[Int] = []
//make sure arrays have the same size
guard inputA.count == inputB.count else { return medianNumbers }
var startIndexA = startIndexA
var endIndexA = endIndexA
var startIndexB = startIndexB
var endIndexB = endIndexB
//make sure the user provides right indexes: start and end
if ((endIndexA - startIndexA) < 0) || ((endIndexB - startIndexB) < 0) {
fatalError("Invalid Input indexes")
}
//if medianA == medianB, we are done, we can append either one twice or both
if (endIndexA - startIndexA == 0) && (endIndexB - startIndexB == 0) {
medianNumbers.append(inputA[0])
medianNumbers.append(inputB[0])
return medianNumbers }
/*if the size == 1, then median = max(ar1[0], ar2[0]) + min(ar1[1],
ar2[1]))/2.0 */
if endIndexA - startIndexA == 1 && endIndexB - startIndexB == 1 {
medianNumbers.append(max(inputA[startIndexA], inputB[startIndexB]))
medianNumbers.append( min(inputA[endIndexA], inputB[endIndexB]))
return medianNumbers
}
let medianA = findMedian(input: inputA, startIndex: startIndexA, endIndex: endIndexA)
let medianB = findMedian(input: inputB, startIndex: startIndexB, endIndex: endIndexB)
if medianB == medianA {
medianNumbers.append(Int(medianA))
medianNumbers.append(Int(medianB))
return medianNumbers }
let medianAIndex = (startIndexA + endIndexA) / 2
let medianBIndex = (startIndexB + endIndexB) / 2
//if medianB>medianA, median is in inputA[n/2...n-1] & inputB[0...n/2]
if medianB > medianA {
if((endIndexA - startIndexA) % 2 == 0) {
startIndexA = medianAIndex
endIndexB = medianBIndex
} else {
startIndexA = medianAIndex
endIndexB = medianBIndex + 1
}
//else median is in inputA[0...n/2] and inputB[n/2...n-1] subarrays
} else {
if((endIndexA - startIndexA) % 2 == 0) {
endIndexA = medianAIndex
startIndexB = medianBIndex
} else {
endIndexA = medianAIndex + 1
startIndexB = medianBIndex
}
}
return findMedianInSortedArray(inputA: inputA, inputB: inputB, startIndexA: startIndexA, endIndexA: endIndexA, startIndexB: startIndexB, endIndexB: endIndexB)
}
func findMedian(input: [Int], startIndex: Int, endIndex: Int) -> Double {
let indexMid = (startIndex + endIndex) / 2
let indexDifference = (endIndex - startIndex)
if indexDifference % 2 == 1 {
return Double(input[indexMid+1]+input[indexMid])/2.0
} else {
return Double(input[indexMid])
}
}
//test the code
func testWithExample(inputA: [Int], inputB: [Int]) {
print("=====Example=====")
print("InputA: \(inputA)")
print("InputB: \(inputB)")
print("Median numbers: ", findMedianInSortedArray(inputA: inputA, inputB: inputB, startIndexA: 0, endIndexA: inputA.count - 1, startIndexB: 0, endIndexB: inputA.count - 1))
}
}
//test the program
let medianNumbers = FindMiddleNumbersInSortedArray()
let input1 = [ 10, 20, 30, 40, 51, 61, 71]
let input2 = [ 15, 25, 31, 86, 600, 700, 900]
medianNumbers.testWithExample(inputA: input1, inputB: input2)
答案 1 :(得分:0)
查找两个已排序数组的中间数字为O(n)
。伪代码样本:
index1 = 0
index2 = 0
for count = 0 to ( array1.count + array2.count ) / 2
if array1[index1] < array2[index2] then
index1 = index1 + 1
else
index2 = index2 + 1
median1 = array1[index1]
median2 = array2[index2]
上面的示例显然不完全正确,并且不处理边缘情况,但应足以为您提供整体构思。
答案 2 :(得分:0)
更新的解决方案:
尝试以下代码,我已经使用以下示例进行了测试。
//tested examples
example(inputA: [1, 2, 3, 4, 50, 62, 77],
inputB: [ 17, 27, 33, 89, 600, 700, 900])
// result: [33 50]
example(inputA: [10, 11, 12, 13, 14, 20],
inputB: [10, 11, 12, 14, 20])
// result : [12, 13]
example(inputA: [10, 11, 12, 13, 14, 800],
inputB: [10, 11, 12, 14, 20, 21, 900])
// result : [13, 14]
example(inputA: [1, 2, 3, 4, 5],
inputB: [7, 8, 9, 10, 11])
// return [7, 5]
func example(inputA: [Int], inputB: [Int]) {
print("---Example----")
print(inputA)
print(inputB)
print(findMedianInSortedArray(inputA: inputA, inputB: inputB, startIndexA: 0, endIndexA: inputA.count-1, startIndexB: 0, endIndexB: inputB.count-1))
}
func findMedianInSortedArray(inputA: [Int], inputB: [Int], startIndexA: Int, endIndexA: Int, startIndexB: Int, endIndexB: Int) -> [Int] {
var findMedianNumArr:[Int] = []
var startIndexA = startIndexA
var endIndexA = endIndexA
var startIndexB = startIndexB
var endIndexB = endIndexB
if ((endIndexA - startIndexA) < 0) || ((endIndexB - startIndexB) < 0) {
print("Invalid Input")
}
if (endIndexA - startIndexA == 0) && (endIndexB - startIndexB == 0) {
findMedianNumArr.append(inputA[0])
findMedianNumArr.append(inputB[0])
return findMedianNumArr
}
if endIndexA - startIndexA == 1 && endIndexB - startIndexB == 1 {
findMedianNumArr.append(max(inputA[startIndexA], inputB[startIndexB]))
findMedianNumArr.append( min(inputA[endIndexA], inputB[endIndexB]))
return findMedianNumArr
}
let medianA = findMedian(input: inputA, startIndex: startIndexA, endIndex: endIndexA)
let medianB = findMedian(input: inputB, startIndex: startIndexB, endIndex: endIndexB)
if medianB == medianA {
let medianArrA = findMedianArray(input: inputA, startIndex: startIndexA, endIndex: endIndexA)
let medianArrB = findMedianArray(input: inputB, startIndex: startIndexB, endIndex: endIndexB)
findMedianNumArr.append(contentsOf: medianArrA)
findMedianNumArr.append(contentsOf: medianArrB)
return findMedianNumArr
}
let medianAIndex = (startIndexA + endIndexA) / 2
let medianBIndex = (startIndexB + endIndexB) / 2
if medianB > medianA {
if((endIndexA - startIndexA) % 2 == 0) {
startIndexA = medianAIndex
endIndexB = medianBIndex
} else {
startIndexA = medianAIndex
endIndexB = medianBIndex + 1
}
} else {
if((endIndexA - startIndexA) % 2 == 0) {
endIndexA = medianAIndex
startIndexB = medianBIndex
} else {
endIndexA = medianAIndex + 1
startIndexB = medianBIndex
}
}
return findMedianInSortedArray(inputA: inputA, inputB: inputB, startIndexA: startIndexA, endIndexA: endIndexA, startIndexB: startIndexB, endIndexB: endIndexB)
}
func findMedian(input: [Int], startIndex: Int, endIndex: Int) -> Double {
let indexMid = (startIndex + endIndex) / 2
let indexDifference = (endIndex - startIndex)
if indexDifference % 2 == 1 {
return Double(input[indexMid+1]+input[indexMid])/2.0
} else {
return Double(input[indexMid])
}
}
func findMedianArray(input: [Int], startIndex: Int, endIndex: Int) -> [Int] {
var findMedianNumArr:[Int] = []
let indexMid = (startIndex + endIndex) / 2
let indexDifference = (endIndex - startIndex)
if indexDifference % 2 == 1 {
findMedianNumArr.append(input[indexMid+1])
}
findMedianNumArr.append(input[indexMid])
return findMedianNumArr
}