Java实现Median of Two Sorted Arrays

算法描述:

求出两个有序数组的中位数。

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    	if (nums1 == null || nums1 == null)
    		throw new NullPointerException();
    	int nums1L = nums1.length;
    	int nums2L = nums2.length;
    	int length = nums1L + nums2L;
    	//需要一个计数器来记录比较次数(需要比较length/2 )
    	int count = 0;
    	//指示两个数组的当前位置
    	int i = 0;
    	int j = 0;
    	//检查数组nums1和nums2为空的情况
    	if (nums1L < 1 && nums2L < 1)
    		return 0;
    	else if (nums1L < 1) {
    		//元素个数为奇数
    	    if (length == 1) return nums2[j];
    		if (length % 2 != 0) {
    			//如果数组1元素个数为0,从当前位置遍历数组2
    			while (j < nums2L) {
    				count++;
    				j++;
    				if (count == (length / 2)) return nums2[j];
    			}
    		} else {
    			//如果数组1元素个数为0,从当前位置遍历数组2
    			while (j < nums2L) {
    				count++;
    				j++;
    				if (count == (length / 2)) return ((double)nums2[j - 1] +nums2[j]) / 2;
    			}
    		}
    	} else if (nums2L < 1) {
    		if (length == 1) return nums1[i];
    		if (length % 2 != 0) {
    			//如果数组2元素个数为0,从当前位置遍历数组2
    			while (i < nums1L) {
    				count++;
    				i++;
    				if (count == (length / 2)) return nums1[i];
    			}
    		} else {
    			//如果数组2元素个数为0,从当前位置遍历数组1
    			while (i < nums1L) {
    				count++;
    				i++;
    				if (count == (length / 2)) return ((double)nums1[i - 1] +nums1[i]) / 2;
    			}
    		}
    		
    	}	
    	// 判断length是奇数还是偶数
    	//如果是奇数,则取中间的那一位
    	if (length % 2 != 0) {
    		//遍历这两个数组,有两种情况发生:1.在没到达边界前计算出中间位置2.到达边界以后算出中间位置
    		while (i < nums1L && j < nums2L) {  			
    			//当count = length / 2时,到了中间的位置,获取它的值
    			count++;
    			if (nums1[i] < nums2[j]) {
    				i++;
    				if (count == (length / 2) && i < nums1L) {
    					if (nums1[i] < nums2[j]) 	  return nums1[i];
    				    else                     	  return nums2[j];
        			} else if (count == (length / 2) && i == nums1L) {
        				if (nums1[ i- 1] < nums2[j])  return nums2[j];
        				else 						  return nums1[ i - 1];
        			} else if (i == nums1L)			  break;
    			} else {
    				j++;
    				if (count == (length / 2) && j < nums2L) {
    					if (nums2[j] < nums1[i]) 	  return nums2[j];
    					else 					 	  return nums1[i];
        			} else if (count == (length / 2) && j == nums2L) {
        				if (nums2[ j - 1] < nums1[i]) return nums1[i];
        				else 						  return nums2[ j - 1];
        			} else if (j == nums2L)			  break;
    			} 			
    		}
    		//数组到达边界,分析是哪种情况:1.数组1到达边界;2.数组2到达边界
    		if (i == nums1L) {
    			//如果数组1越界,从当前位置遍历数组2
    			while (j < nums2L) {
    				count++;
    				j++;
    				if (count == (length / 2)) return nums2[j];
    			}
    		} else if (j == nums2L) {
    			//如果数组2越界,从当前位置遍历数组1
    			while (i < nums1L) {
    				count++;
    				i++;
    				if (count == (length / 2)) return nums1[i];
    			}
    		}	
    	} else {
    		//否则取中间两位的平均
    		//遍历这两个数组,有两种情况发生:1.在没到达边界前计算出中间位置2.到达边界以后算出中间位置
    		while (i < nums1L && j < nums2L) {  			
    			//当count = length / 2时,到了中间的位置,获取它的值
    			count++;
    			if (nums1[i] < nums2[j]) {
    				i++;
    				if (count == (length / 2) && i < nums1L) {
    					if (nums1[i] < nums2[j]) {
    						return ((double)nums1[i - 1] +nums1[i]) / 2;
    					}
    				    else {
    				    	return ((double)nums2[j] + nums1[i - 1]) / 2; 
    				    }
        			} else if (count == (length / 2) && i == nums1L) {
        				return ((double)nums1[i - 1] +nums2[j]) / 2;
        			} else if (i == nums1L)			  break;
    			} else {
    				j++;
    				if (count == (length / 2) && j < nums2L) {
    					if (nums2[j] < nums1[i]) {
    						return ((double)nums2[j - 1] +nums2[j]) / 2;
    					}
    				    else {
    				    	return ((double)nums1[i] + nums2[j - 1]) / 2; 
    				    }
        			} else if (count == (length / 2) && j == nums2L) {
        				return ((double)nums2[j - 1] +nums1[i]) / 2;
        			} else if (j == nums2L)			  break;
    			}	
    		}
    		//数组到达边界,分析是哪种情况:1.数组1到达边界;2.数组2到达边界
    		if (i == nums1L) {
    			//如果数组1越界,从当前位置遍历数组2
    			while (j < nums2L) {
    				count++;
    				j++;
    				if (count == (length / 2)) return ((double)nums2[j] + nums2[j - 1]) / 2; 
    			}
    		} else if (j == nums2L) {
    			//如果数组2越界,从当前位置遍历数组1
    			while (i < nums1L) {
    				count++;
    				i++;
    				if (count == (length / 2)) return ((double)nums1[i] + nums1[i - 1]) / 2;
    			}
    		}
    	}
    	return 0;    
    }
}


笔记:

  1. 变量定义在最前面,这样代码读起来更好;
  2. 方法要先进行传入参数的检查,确保传入参数正确;
  3.  对特殊情况要先考虑清楚,在这个题中,要考虑其中一个或两个元素个数都为的情况;
  4. 算法在考虑效率时,并列条件只考虑最复杂的一个条件。循环是主要的效率考虑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值