java算法:4. 寻找两个正序数组的中位数(困难)

题目:

  1. 寻找两个正序数组的中位数
    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
    详见:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

思路:

本题的思路有两种,力扣上的官方也有所解读,但是我理解的是将这两种思路合并成为一种:
  假设我们已经把两个数组合并了,中位数的索引位置得到的是k,相当于在这个数组中有k个元素比中位数小,而这个k值我们又很好求得(因为两个数组的数组长度都知道),所以我们只需要求得第k小的元素是哪一个或者哪两个就可以了。
  在求第k小的元素时,因为已知的两个数组都是有序的,我们可以定义两个指针i和j,分别从两个数组的0位置开始遍历,如果nums1[i]<=nums2[j],遍历nums1数组,i++;如果nums2[j]<nums1[i],遍历nums2数组,j++,直到遍历到k就停止,并得到那一个数或者两个数。然后就求得中位数了。

代码:

上述思路的代码:这个代码其实还可以优化,不过为了方便大家理解,我代码就写杂了一点:

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    	int n= nums1.length+nums2.length;
    	int q,p;
    	if(n%2==0) {
    		q=n/2-1;
    		p=n/2;
    	}else {
    		q=p=n/2;
    	}
    	double result = this.mergeArr(nums1,nums2,q,p);
    
    	return result;
    }
    
//    合并数组
	private double mergeArr(int[] nums1, int[] nums2,int q,int p) {
		// TODO Auto-generated method stub
		int n = nums1.length,m=nums2.length;
		if(n==0) {
			return (nums2[q]+nums2[p])/2.0;
		}
		if(m==0) {
			return (nums1[q]+nums1[p])/2.0;
		}
		int i=0,j=0,k=0;
		int result1 = 0;
		int result2 = 0;
		okk:
		while(i<n||j<m) {
			while(nums1[i]<=nums2[j]) {
				if(k==q) result1=nums1[i];
				if(k==p) {
					result2=nums1[i];
					break okk;
				}
				i++;
				k++;
				if(i==n) {
					while(j<m) {
						if(k==q) result1=nums2[j];
						if(k==p) {
							result2=nums2[j];
							break okk;
						}
						j++;
						k++;
					}
					break okk;
				}
			}
			while(nums2[j]<=nums1[i]) {
				if(k==q) result1=nums2[j];
				if(k==p) {
					result2=nums2[j];
					break okk;
				}
				j++;
				k++;
				if(j==m) {
					while(i<n) {
						if(k==q) result1=nums1[i];
						if(k==p) {
							result2=nums1[i];
							break okk;
						}
						i++;
						k++;
					}
					break okk;
				}
			}
			
		}
		return (result1+result2)/2.0;
	}

}

有同学还是想合并成一个新数组,这里也给出了相应的代码

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    	int[] newArr = this.mergeArr(nums1,nums2);
    	int n= newArr.length;
    	double result=0;
    	if(n%2==0) {
    		result =  (newArr[n/2-1]+newArr[n/2])/2.0;
    	}else {
    		result = newArr[n/2];
    	}
    	return result;
    }
    
//    合并数组
	private int[] mergeArr(int[] nums1, int[] nums2) {
		// TODO Auto-generated method stub
		int n = nums1.length,m=nums2.length;
		if(n==0) {
			return nums2;
		}
		if(m==0) {
			return nums1;
		}
		int[] newArr = new int[n+m];
		int i=0,j=0,k=0;
		okk:
		while(i<n||j<m) {
			while(nums1[i]<=nums2[j]) {
				newArr[k] = nums1[i];
				i++;
				k++;
				if(i==n) {
					while(j<m) {
						newArr[k]=nums2[j];
						j++;
						k++;
					}
					break okk;
				}
			}
			while(nums2[j]<=nums1[i]) {
				newArr[k] = nums2[j];
				j++;
				k++;
				if(j==m) {
					while(i<n) {
						newArr[k]=nums1[i];
						i++;
						k++;
					}
					break okk;
				}
			}
			
		}
		return newArr;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

松果Tech

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值