Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >2021-06-29:在两个都有序的数组中找整体第K小的数。

2021-06-29:在两个都有序的数组中找整体第K小的数。

作者头像
福大大架构师每日一题
发布于 2021-08-05 08:13:53
发布于 2021-08-05 08:13:53
50000
代码可运行
举报
运行总次数:0
代码可运行

2021-06-29:在两个都有序的数组中找整体第K小的数。

福大大 答案2021-06-29:

1.A和B长度不等的时候,需要把A和B的长度变成相等。

A是短数组,B是长数组。

第k小的数,k从1开始。

k<=短,都取前k个数,变成等长。

短<k<=长,长取中,长扣1。

长<k<=和,两个数组都取后 变成等长,两个数组都需要扣掉1个元素,小被干,都需要扣掉左边。

2.A和B长度相等的时候。分长度是偶数和长度是奇数两种情况。都是求中位数。

2.1.A和B长度相等,并且长度是偶数。

A=[A1,A2,A3,A4]

B=[B1,B2,B3,B4]

当A2==B2时,取A2。

当A2>B2时,B1、B2、A3、A4去掉。递归。

2.2.A和B长度相等,并且长度是奇数。

A=[A1,A2,A3,A4,A5]

B=[B1,B2,B3,B4,B5]

当A3==B3时,取A3。

当A3>B3时,B1、B2、A3、A4、A5去掉。当A2<=B3时,取B3;否则去掉B3,递归。

时间复杂度是O(log(min(M,N)))。

代码用golang编写。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {
    arr1 := []int{1, 3}
    arr2 := []int{2}
    ret := findMedianSortedArrays(arr1, arr2)
    fmt.Println(ret)
}

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    size := len(nums1) + len(nums2)
    even := (size & 1) == 0
    if len(nums1) != 0 && len(nums2) != 0 {
        if even {
            return float64(findKthNum(nums1, nums2, size/2)+findKthNum(nums1, nums2, size/2+1)) / 2.0
        } else {
            return float64(findKthNum(nums1, nums2, size/2+1))
        }
    } else if len(nums1) != 0 {
        if even {
            return float64((nums1[(size-1)/2] + nums1[size/2]) / 2)
        } else {
            return float64(nums1[size/2])
        }
    } else if len(nums2) != 0 {
        if even {
            return float64((nums2[(size-1)/2] + nums2[size/2]) / 2)
        } else {
            return float64(nums2[size/2])
        }
    } else {
        return 0
    }
}

// 进阶问题 : 在两个都有序的数组中,找整体第K小的数
// 可以做到O(log(Min(M,N)))
func findKthNum(arr1 []int, arr2 []int, kth int) int {
    longs := twoSelectOne(len(arr1) >= len(arr2), arr1, arr2)
    shorts := twoSelectOne(len(arr1) < len(arr2), arr1, arr2)
    l := len(longs)
    s := len(shorts)
    if kth <= s { // 1)
        return getUpMedian(shorts, 0, kth-1, longs, 0, kth-1)
    }
    if kth > l { // 3)
        if shorts[kth-l-1] >= longs[l-1] {
            return shorts[kth-l-1]
        }
        if longs[kth-s-1] >= shorts[s-1] {
            return longs[kth-s-1]
        }
        return getUpMedian(shorts, kth-l, s-1, longs, kth-s, l-1)
    }
    // 2)  s < k <= l
    if longs[kth-s-1] >= shorts[s-1] {
        return longs[kth-s-1]
    }
    return getUpMedian(shorts, 0, s-1, longs, kth-s, kth-1)
}

// A[s1...e1]
// B[s2...e2]
// 一定等长!
// 返回整体的,上中位数!8(4) 10(5) 12(6)
func getUpMedian(A []int, s1 int, e1 int, B []int, s2 int, e2 int) int {
    mid1 := 0
    mid2 := 0
    for s1 < e1 {
        // mid1 = s1 + (e1 - s1) >> 1
        mid1 = (s1 + e1) / 2
        mid2 = (s2 + e2) / 2
        if A[mid1] == B[mid2] {
            return A[mid1]
        }
        // 两个中点一定不等!
        if ((e1 - s1 + 1) & 1) == 1 { // 奇数长度
            if A[mid1] > B[mid2] {
                if B[mid2] >= A[mid1-1] {
                    return B[mid2]
                }
                e1 = mid1 - 1
                s2 = mid2 + 1
            } else { // A[mid1] < B[mid2]
                if A[mid1] >= B[mid2-1] {
                    return A[mid1]
                }
                e2 = mid2 - 1
                s1 = mid1 + 1
            }
        } else { // 偶数长度
            if A[mid1] > B[mid2] {
                e1 = mid1
                s2 = mid2 + 1
            } else {
                e2 = mid2
                s1 = mid1 + 1
            }
        }
    }
    return getMin(A[s1], B[s2])
}

func getMin(a int, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}

func twoSelectOne(c bool, a []int, b []int) []int {
    if c {
        return a
    } else {
        return b
    }
}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzuo/coding-for-great-offer/blob/main/src/class12/Code03_FindKthMinNumber.java)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Data Structures and Algorithms Basics(005):Divid conquer
在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如二分搜索,排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)......
用户5473628
2019/08/08
5330
LeetCode - #4 求两个有序数组的中间值
我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长[1])的 Swift 算法题题解整理为文字版以方便大家学习与阅读。
Swift社区
2021/11/26
7090
LeetCode - #4 求两个有序数组的中间值
两个正序数组 找中位数_leetcode合并两个有序数组
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
全栈程序员站长
2022/09/22
3550
【Day27】 LeetCode算法刷题(思路+注释)[801. 使序列递增的最小交换次数 ]
/ 示例 1: 输入: nums1 = [1,3,5,4], nums2 = [1,2,3,7] 输出: 1 解释: 交换 A[3] 和 B[3] 后,两个数组如下: A = [1, 3, 5, 7] , B = [1, 2, 3, 4] 两个数组均为严格递增的。 / 示例 2: 输入: nums1 = [0,3,5,8,9], nums2 = [2,1,4,6,9] 输出: 1
.29.
2022/11/15
2280
【Day27】 LeetCode算法刷题(思路+注释)[801. 使序列递增的最小交换次数 ]
LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Michael阿明
2020/07/13
1K0
LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)
【递归打卡2】求两个有序数组的第K小数
给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数。要求时间复杂度O(log(m1 + m2))。
帅地
2019/03/30
1.8K0
算法细节系列(8):4. Median of Two Sorted Arrays
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/70159055
用户1147447
2019/05/26
4630
004. 寻找两个正序数组的中位数 | Leetcode题解
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
苏南
2020/12/16
1.5K0
004. 寻找两个正序数组的中位数 | Leetcode题解
【每天一道编程系列-2018.2.18】(Ans)
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)). 
yesr
2019/03/14
2960
两个有序数组的第n大数「建议收藏」
取A数组的中间元素mid1,取B数组的中间元素mid2,先比較这两个元素的大小。假设这两个元素相等,则直接返回A[mid1],假设A[mid1]<B[mid2],则mid1左側的元素能够去掉,B数组右側的元素能够去掉。这里还要区分数组元素个数为偶数奇数的情况,假设元素个数为偶数,则mid1元素也要去掉。假设A[mid1]<B[mid2]的情况与此类似。时间复杂度为O(logn)
全栈程序员站长
2022/07/10
4200
2021-04-05:给两个长度分别为M和N的整型数组...
2021-04-05:给两个长度分别为M和N的整型数组nums1和nums2,其中每个值都不大于9,再给定一个正数K。 你可以在nums1和nums2中挑选数字,要求一共挑选K个,并且要从左到右挑。返回所有可能的结果中,代表最大数字的结果。
福大大架构师每日一题
2021/04/05
4560
2021-04-05:给两个长度分别为M和N的整型数组...
【LeetCode题解-004】Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
周三不加班
2019/09/04
5010
【LeetCode题解-004】Median of Two Sorted Arrays
leetcode算法题js版
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
一粒小麦
2019/07/18
9290
leetcode算法题js版
LeetCode 2040. 两个有序数组的第 K 小乘积(嵌套二分查找)
给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k ,请你返回第 k (从 1 开始编号)小的 nums1[i] * nums2[j] 的乘积,其中 0 <= i < nums1.length 且 0 <= j < nums2.length 。
Michael阿明
2022/01/07
5730
LeetCode 1868. 两个行程编码数组的积(双指针)
行程编码(Run-length encoding)是一种压缩算法,能让一个含有许多段连续重复数字的整数类型数组 nums 以一个(通常更小的)二维数组 encoded 表示。
Michael阿明
2021/09/06
7020
求两个不等长、有序数组a和b的中位数的最优解(排除法 )
不断删掉数组中肯定不是第k小的那些数字,从而能够不断地减小数组,在这个过程中,我们要找的那个数字的序号(k)也会不断地减小。
陈黎栋
2020/02/18
6590
【Leetcode】移除元素、合并两个有序数组
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
P_M_P
2024/01/18
1290
【Leetcode】移除元素、合并两个有序数组
LeetCode 321. 拼接最大数(单调栈)*
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。 现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
Michael阿明
2021/02/19
2830
重中之重的二分查找
There are two sorted arrays nums1 and nums2 of size m and n respectively.
王脸小
2020/07/28
4870
【寻找两个正序数组的中位数LeetCode-4】
原题链接 https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
junedayday
2021/08/05
2220
推荐阅读
相关推荐
Data Structures and Algorithms Basics(005):Divid conquer
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验