本文已参与[新人创作]活动,一起开启掘金创作之路。
题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
求第一个数组和第二个数组的长度, 用length1和length2来记录 求length1和length2的和 然后根据奇偶性来中中间数的下标 然后用双指针同时遍历两数组,求中间数
代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
/*
题目已知:
两个正序的数组,从小到大
题目要求:
找出两个正序数组的中位数
时间复杂度O(log(m+n))
解放方法:
先求两数组的长度之和
判断数组奇偶
然后遍历两数组,查找中间值
*/
// length1记录数组num1的长度
int length1=nums1.length;
// length2记录数组num2的长度
int length2=nums2.length;
// 如果其中一个数组长度为0
if(length1==0||length2==0){
// 如果nums1的长度为0
if(length1==0){
// 如果nums2的长度为偶数
if(length2%2==0){
return (nums2[length2/2-1]+nums2[length2/2])/2.0;
}
// 如果nums2的长度为奇数
else{
return nums2[length2/2];
}
}
// 如果nums2的长度为0
else{
// 如果nums1的长度为偶数
if(length1%2==0){
return (nums1[length1/2-1]+nums1[length1/2])/2.0;
}
// 如果nums1的长度为奇数
else{
return nums1[length1/2];
}
}
}
// 两者长度均不为空
else{
// length记录数组的长度之和
int length=length1+length2;
// 如果长度之和为奇数
if(length%2!=0){
// 返回第几大的元素
int mid=length/2+1;
// 记录从小到大,第几个元素
int order=0;
// 遍历数组
for(int i=0,j=0;i<length1||j<length2;){
// 如果其中一个已经遍历完
if(i>=length1||j>=length2){
// nums1遍历完
if(i>=length1){
if(order<mid){
return nums2[j-1+mid-order];
}
}
//nums2遍历完
else{
if(order<mid){
return nums1[i-1+mid-order];
}
}
}
// 两个数组均未遍历完
if(i<length1&&j<length2){
// 比较元素大小
// nums1的元素不大于nums2的元素
if(nums1[i]<=nums2[j]){
// 计数加一
order++;
// 判断order是否等于mid
if(order==mid){
return nums1[i];
}
// nums1下标加一
i++;
}
// nums2的元素较小
else{
// 计数加一
order++;
// 判断order是否等于mid
if(order==mid){
return nums2[j];
}
// nums2下标加一
j++;
}
}
}
}
// 如果长度之和为偶数
else{
// 记录mid1,mid2记录中间两个数的排次
int mid1=length/2;
int mid2=length/2+1;
// 记录从小到大,第几个元素
int order=0;
// 记录中间第一个数的大小
int element1=0;
// 遍历数组
for(int i=0,j=0;i<length1||j<length2; ){
// 如果其中一个已经遍历完
if(i>=length1||j>=length2){
// nums1遍历完
if(i>=length1){
//表明一个还没找到
if(order<mid1){
return (nums2[j-1+mid1-order]+nums2[j-1+mid2-order])/2.0;
}
//表明已找到第一个
else{
return (element1+nums2[j])/2.0;
}
}
//nums2遍历完
else{
if(order<mid1){
return (nums1[i-1+mid1-order]+nums1[i-1+mid2-order])/2.0;
}
else{
return (element1+nums1[i])/2.0;
}
}
}
// 如果两个数组均为遍历完
if(i<length1&&j<length2){
// 如果nums1的元素不大于nums2的元素
if(nums1[i]<=nums2[j]){
// 计数加一
order++;
// 如果为中间的两个数
if(order==mid1){
element1=nums1[i];
}
else if(order==mid2){
// 此时两个均找到
return (element1+nums1[i])/2.0;
}
// 遍历下一个
i++;
}
// 如果nums2的元素较小
else{
// 计数加一
order++;
// 如果为中间的两个数
if(order==mid1){
element1=nums2[j];
}
else if(order==mid2){
// 此时两个均找到
return (element1+nums2[j])/2.0;
}
// 遍历下一个
j++;
}
}
}
}
}
return 0;
}
}
/*
写题中间遇到的错误点:
遍历数组时,结束条件用的||,i<length1||j<length2
忘记考虑其中一个数组先遍历完的情况
*/