「这是我参与11月更文挑战的4天,活动详情查看:2021最后一次更文挑战」。
前言
一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,希望通过这种方式养成持续学习的习惯。因为我是做iOS开发的,主要是用Objective-C语言,最近也在学习Swift,所以本系列的题解都将使用swift语言完成,本文更新的是LeetCode中HOT100的第4题004寻找两个正序数组的中位数。
题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
分析
本题的目的是从两个有序数组中找出合并中位数,并且如果两个数组元素总个数为奇数时,中位数只有一个,总个数为偶数时,中位数有两个,取这两个的平均值。
因此,比较简单的办法就是讲两个有序数组合并成一个有序数组,然后根据总个数的奇偶找出中位数。
本文的题解就是通过这种方法实现,只是本文在合并时没有完全合并两个数组,只合并了数组的一半,然后直接取中间的数据进行计算即可。
题解
class KLLC004 {
func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
let totalCount = nums1.count + nums2.count
//两个数组都为空的处理
if totalCount == 0 {
return -1.0
}
//合并记录数组
var mergeArr = Array<Int>(repeating: 0, count: totalCount)
//合并过程中对应数组的下标
var index1 = 0, index2 = 0, index0 = 0
while index1 < nums1.count || index2 < nums2.count {
//将数组1中小于数组2中index2对应当前值的数全部合并
while index1 < nums1.count && (index2 == nums2.count || nums2[index2] >= nums1[index1]) {
mergeArr[index0] = nums1[index1]
index0 += 1
index1 += 1
}
//将数组2中小于数组1中index1对应当前值的数全部合并
while index2 < nums2.count && (index1 == nums1.count || nums1[index1] >= nums2[index2]) {
mergeArr[index0] = nums2[index2]
index0 += 1
index2 += 1
}
//如果合并数据过半,则处理结束
if index0 > totalCount/2 {
break
}
}
//根据总个数的奇偶性计算中位数
if totalCount % 2 == 0 {
return Double(mergeArr[totalCount/2 - 1] + mergeArr[totalCount/2])/2
} else {
return Double(mergeArr[totalCount/2])
}
}
}