做leetcode题目的第二天,我是按照分类来做的,做的第一类是Array类,碰见的第二道题目,也就是今天做的这个,题目难度为hard。题目不难理解,但是要求到了时间复杂度,就需要好好考虑使用一下算法了。刚开始没啥思路,就用暴力的方法,用双层循环遍历的一下两个已经排好序的数组 ,在中间位置停止找道中位数。这样时间复杂度是肯定不能满足题目要求的,但是程序测试还是过了。

苦于自己没有思路,又不甘心就这样水过一道题,还是搜了一下博客,膜拜了一下大神。最好的方法是将中位数  -- 两个数组数据排好序之后的(m+n)/2  位置左右的数(奇,偶)(程序里面会有体现)--看成是求排好序的数组的第k = (m+n)/2 小的数据,然后采用类似于二分的方法求解。

在这里先把题目粘过来:

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

  1. nums1 = [, ]
  2. nums2 = []
  3.  
  4. The median is 2.0
  1.  

Example 2:

  1. nums1 = [, ]
  2. nums2 = [, ]
  3.  
  4. The median is ( + )/ = 2.5

这里先把我的java代码贴一下:(给自己个警示)

  1. public class Solution {
  2. public double findMedianSortedArrays(int[] nums1, int[] nums2) {
  3. int len = nums1.length+nums2.length;
  4. int []ans_c = new int[len];
  5. boolean flag = false;
  6. int i=,j=;
  7. int k=;
  8. for(;k<len/+;k++){
  9. if(i<nums1.length && j<nums2.length){
  10. if(nums1[i]<=nums2[j]){
  11. ans_c[k]=nums1[i];
  12. i++;
  13. }
  14. else{
  15. ans_c[k]=nums2[j];
  16. j++;
  17. }
  18. }
  19. else if(i<nums1.length){
  20. ans_c[k]=nums1[i];
  21. i++;
  22. }
  23. else{
  24. ans_c[k]=nums2[j];
  25. j++;
  26. }
  27. }
  28. if(len%==){
  29. return (double)(ans_c[k-]+ans_c[k-])/;
  30. }
  31. else{
  32. return (double)ans_c[k-];
  33. }
  34. }
  35. }

C++ 代码:

这里对于求解思路呢我就不做过多的说明了,把别人的博客链接发过来自己欣赏一下吧,我想做的是对自己写的代码进行一下注释说明,以便自己之后回忆起来好理解。

这里摘录一下他的分析过程

  1. 最后从medianof two sorted arrays中看到了一种非常好的方法。原文用英文进行解释,在此我们将其翻译成汉语。该方法的核心是将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。
  2.  
  3. 首先假设数组AB的元素个数都大于k/,我们比较A[k/-]和B[k/-]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/-]<B[k/-],这表示A[]到A[k/-]的元素都在AB合并之后的前k小的元素中。换句话说,A[k/-]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。
  4.  
  5. 证明也很简单,可以采用反证法。假设A[k/-]大于合并之后的第k小值,我们不妨假定其为第(k+)小值。由于A[k/-]小于B[k/-],所以B[k/-]至少是第(k+)小值。但实际上,在A中至多存在k/-1个元素小于A[k/-],B中也至多存在k/-1个元素小于A[k/-],所以小于A[k/-]的元素个数至多有k/+ k/-,小于k,这与A[k/-]是第(k+)的数矛盾。
  6.  
  7. A[k/-]>B[k/-]时存在类似的结论。
  8.  
  9. A[k/-]=B[k/-]时,我们已经找到了第k小的数,也即这个相等的元素,我们将其记为m。由于在AB中分别有k/-1个元素小于m,所以m即是第k小的数。(这里可能有人会有疑问,如果k为奇数,则m不是中位数。这里是进行了理想化考虑,在实际代码中略有不同,是先求k/,然后利用k-k/2获得另一个数。)
  10.  
  11. 通过上面的分析,我们即可以采用递归的方式实现寻找第k小的数。此外我们还需要考虑几个边界条件:
  12.  
  13. 如果A或者B为空,则直接返回B[k-]或者A[k-];
  14. 如果k1,我们只需要返回A[]和B[]中的较小值;
  15. 如果A[k/-]=B[k/-],返回其中一个;

分析

这里我补充说明几个问题:

第一是两个数组长度之和是有奇、偶之分的,奇数时我们需要求解第 k=(m+n)/2 + 1 小数据 ,偶数时我们需要求解 第 k1 = (m+n) / 2  和第 k2=(m+n)/2+1

小,然后 k = (k1+k2)/2

第二是这两个数组并没有合并,我们需要两个没有完全排好序的数组的第k小数,可以分别在两个数组中求第 k/2 小的数进行比较,这就和上面粘贴的分析相结合了。

第三是有可能其中一个数组长度较小,小于 k/2,这是我们就需要在程序中进行判断了,每次都将长度较小的数组置于,传递参数的第一个位置,然后江数组长度与 k/2 比较,如果m>k/2,就直接选取第  pa =  k/2小数据,不然就取第一个数组的长度 pa = m,pb = k-pa,然后将A[pa-1]于B[pb-1](第pb小对应数组的位置应该为pb-1)进行比较,这里痛上面的分析过程

代码:

  1. class Solution {
  2. public:
  3. double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
  4. int total = nums1.size()+nums2.size();
  5. if(total% == ){ //判断奇偶
  6. return (finKth(nums1,nums2,total/)+finKth(nums1,nums2,total/+))/;
  7. }
  8. else{
  9. return finKth(nums1,nums2,total/+);
  10. }
  11. }
  12. public:
  13. double finKth(vector<int> nums1,vector<int> nums2,int k){ // 寻找第k小
  14. if( nums1.size() > nums2.size()){ // 将nums1永远作为长度较小的数组
  15. return finKth(nums2,nums1,k);
  16. }
  17. if( nums1.size() == ){ //如果其中一个数组长度为0则第k小就是nums2的第k小
  18. return nums2[k-];
  19. }
  20. if(k == ){ //k=1 说明 一种情况是 两个数组长度都为 1 这是 需要求 (1+1)/2 直接返回两个数组中较小的一个
  21. return nums1[]<nums2[]?nums1[]:nums2[]; // 另一种情况是 每次递归都会去除一部分元素,使得第k小变成第k-p小 当k-p为一时,就可以返回,两个数组nums1[0],nums2[0]中较小的一个了
  22. }
  23. int findKsa = nums1.size() <k/ ? nums1.size() : k/;
  24. int findKsb = k-findKsa;
  25. if(nums1[findKsa-]<nums2[findKsb-]){
  26. return finKth(vector<int>(nums1.begin()+findKsa,nums1.end()),nums2,k-findKsa);
  27. } //对这里的vector向量的传递做个说明:因为每次都需要去除一部分数据 ,所以使用 vector 的 begin 和 end 方法截取中间的一部分元素
  28. else if(nums1[findKsa-]>nums2[findKsb-]){
  29. return finKth(nums1,vector<int>(nums2.begin()+findKsb,nums2.end()),k-findKsb);
  30. }
  31. else{
  32. return nums1[findKsa-];
  33. }
  34. }
  35. };

在这里说说自己做题的感觉,每次看到题都没有思路,做题只是能看懂别人的思路和代码········希望自己逐渐进步,直到可以独立作出大部分的题目(可以自己独立写出自己的的思路)

 
 

Leetcode Array 4 Median of Two Sorted Arrays的更多相关文章

  1. 【LeetCode】4. Median of Two Sorted Arrays (2 solutions)

    Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...

  2. 《LeetBook》leetcode题解(4): Median of Two Sorted Arrays[H]——两个有序数组中值问题

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  3. leetcode.C.4. Median of Two Sorted Arrays

    4. Median of Two Sorted Arrays 这应该是最简单最慢的方法了,因为本身为有序,所以比较后排序再得到中位数. double findMedianSortedArrays(in ...

  4. leetcode第二题--Median of Two Sorted Arrays

    Problem:There are two sorted arrays A and B of size m and n respectively. Find the median of the two ...

  5. 【一天一道LeetCode】#4 Median of Two Sorted Arrays

    一天一道LeetCode (一)题目 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find th ...

  6. 【LeetCode OJ】Median of Two Sorted Arrays

    题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ 题目:There are two sorted arrays nums1 ...

  7. 【LeetCode】004. Median of Two Sorted Arrays

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  8. 【LeetCode】4. Median of Two Sorted Arrays 寻找两个正序数组的中位数

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:数组,中位数,题解,leetcode, 力扣,python ...

  9. 【leetcode】4. Median of Two Sorted Arrays

    题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of t ...

随机推荐

  1. markdown的使用说明

    markdown 你很牛 说点废话 背景 md 经常喜欢写点东西的人,是不是觉得用各种笔记软件或者是html,排版总是让你感到蛋蛋的忧伤,本来满腹经纶,最后由于不好排版,阅读体验差,最后...but. ...

  2. Codeforces Round #363 (Div. 2) C dp或贪心 两种方法

    Description Vasya has n days of vacations! So he decided to improve his IT skills and do sport. Vasy ...

  3. 所驼门王的宝藏(bzoj 1924)

    Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...

  4. Python之Django框架

    1.Django简介 Python下有多款不同的 Web 框架,Django是最有代表性的一种.许多成功的网站和APP都基于Django. Django是一个开源的Web应用框架,由Python写成. ...

  5. 介绍一个牛X的样式counter

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  6. duilib入门简明教程 -- 界面布局(9) (转)

    原文转自:http://www.cnblogs.com/Alberl/p/3343806.html     上一个教程实现的标题栏代码中,并没有看到处理自适应窗口大小的代码,但是窗口大小变化后,按钮的 ...

  7. 老郭带你学数据结构(C语言系列)1-线性表之静态顺序表

    在学习之前,先说下我的软件情况,操作系统是manjaro linux 今天刚刚升级的,编辑器是vim8.0.55,编译器是gcc 6.2.1,调试器是gdb 7.12,版本再低点也可以,只要gcc版本 ...

  8. XPath语法 在C#中使用XPath例子与用法

    XPath可以快速定位到Xml中的节点或者属性.XPath语法很简单,但是强大够用,它也是使用xslt的基础知识.示例Xml: <?xml version="1.0" enc ...

  9. springBoot api接口

    application/json 请求接口 @RequestMapping(value = "/getBaseData", method = RequestMethod.POST, ...

  10. TCP/IP握手协议

    转自:http://www.js123.net/t/n/n/2013/4/28/n_272.shtml 这篇介绍的也很棒:http://www.cnblogs.com/rootq/articles/1 ...