• **leetcode刷题笔记四 两个有序序列的中位数**


    leetcode刷题笔记四 两个有序序列的中位数

    原地址:两个有序序列的中位数

    问题描述:

    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)).

    You may assume nums1 and nums2 cannot be both empty.

    Example 1:

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

    Example 2:

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

    思路分析:

    1.不考虑复杂度的情况下,最简单直接的方法是将两个数组进行合并,对合并后的数组进行排序,根据合并后数组的长度的奇偶获取对应的中位数位置。

    代码如下:

    def findMedianSortedArrays(nums1: Array[Int], nums2: Array[Int]): Double = {
     val nums = (nums1 ++ nums2).sorted
     if (nums.length%2 == 1){
         return nums(nums.length/2)
       }
     else{
         return (nums(nums.length/2-1)+nums(nums.length/2))/2.0
       }
     }
    

    执行结果:

    image-20200405042852060

    2.对上一种思路的优化,问题的本质在于寻找有序序列中第K个数,可以使用计数器进行计数,依据遍历至第K次进行返回。

    3.博客https://www.cnblogs.com/bonelee/p/10217507.html中提到了一种‘割’的方法。获取第K大数的过程,是对两个数组进行分割,分割为前K-1个数,第K大数, K之后的数。

    以单数组为例,其过程就是对第K大数进行分割。

    对于本题中的两数组的情况,假定

    ...LA Ca Ra...
    ...LB CB RB...

    由于数组本身是有序的,LA <= RA , LB <= RB,CA CB为分割线

    //
    func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
        //获取整个字符串长度
        total := len(nums1) + len(nums2)
        //总长度为偶数,中位数考虑中间位置2个
        if (total % 2 == 0) {
            left := find(nums1, 0, nums2, 0, total/2)
            right := find(nums1, 0, nums2, 0, total/2 + 1)
            //fmt.Printf("left: %d, right: %d, ans: %f", left, right, float64(left +right)/2)
            return float64(left + right)/2
        } else {
            //否则只考虑最中间的一个
            return float64(find(nums1, 0, nums2, 0, total/2 + 1))
        }
        return 0.0
    }
    
    func find(nums1 []int, i int, nums2 []int, j int, k int) int {
        //保证nums1 长度 小于等于 nums2长度
        if len(nums1) - i > len(nums2) - j {
            return find(nums2, j, nums1, i, k)
        }
        //只取1个时
        if k == 1{
            //若nums1 已经遍历完了,返回nums2的遍历的头部
            if len(nums1) == i{
                return nums2[j]
            } else if nums1[i] < nums2[j] {
                //否则,取二者头部较小的元素
                return nums1[i]
            } else {
                return nums2[j]
            }
        }
        //若nums1 已经遍历完了,返回nums2的遍历结果
        if len(nums1) == i {
            return nums2[j + k - 1]
        }
        //由于nums1较短,需要判断nums1是否能到达i + k/2
        si := 0
        if len(nums1) < i + k/2 {
            si = len(nums1)
        } else {
            si = i + k/2
        }
        sj := j + k - k/2
        //根据指定位置的对比,判断哪一部份数被排除
        if nums1[si-1] > nums2[sj-1] {
            return find(nums1, i, nums2, sj, k-(sj-j))
        } else {
            return find(nums1, si, nums2, j, k-(si-i))
        }
    }
    
  • 相关阅读:
    Centos7安装go.10.1环境
    centos7安装PHP5
    Linux 无文件攻击memfd_create()具体操作步骤
    centos7 '/mnt/hgfs'下共享文件夹不显示问题
    fiddler连接代理手机无法上网问题解决办法
    centos 镜像软件安装包版本低,手动安装过程
    0 upgraded, 0 newly installed, 0 to remove and 112 not upgraded解决方法
    JavaScript高级程序设计(第3版)第七章读书笔记
    JavaScript高级程序设计(第3版)第六章读书笔记
    JavaScript高级程序设计(第3版)第五章读书笔记
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/14011632.html
Copyright © 2020-2023  润新知