LeetCode第四题之小白对二分法的粗浅认识

一、题目分析。

       题目:给定两个升序子数组A、B,查找升序和数组的中位数。

       问题类型:查找问题。

       关键条件:升序,中位数。

二、解法模型选择 初步分析。

       查找目标:中位数。

       数学描述:m个升序元素中,m为偶数时,第 m/2(整数除法)个与第 m/2+1 个元素的算术平均数;m为奇数时,第 m/2+1 个元素。

       计算机描述:主要是一个查找问题。查找第 m/2 个与第 m/2+1 个元素,然后根据m的奇偶情况去返回相应答案。

       特殊条件:两个数组是升序的,待查找目标也与顺序有关。

       考虑使用方法:二分法。

       二分法的原理:每次缩小一半的查找范围。(即不是根据所在位置去评价元素,而是根据目标元素去评价某个范围。)

       二分法的原则:每次缩小范围,不能舍弃目标元素;每次都要改变搜索范围,且不能陷入“局部循环”,避免程序循环无法终止。

三、程序设计中的循环主干。

       核心问题:如何查找两个升序子数组,所组成的和数组的第k个元素。

       常规的查找方法:这是一个顺序结构。设置两个指向子数组的指针,更加由小到大的原则,依次比较,找到第k个元素。需要遍历k次,查找范围长度为k。(一个个元素遍历,遍历长度为k的范围)

       二分法的查找方法:我们希望不要一个个元素遍历,一个个元素去判断、舍弃,而是一次性舍弃掉一半的元素。

       我们上哪去找这些被舍弃的元素?在给定长度为k的范围,这个元素都不大于第k个元素。我们可以找子数组A、B的前k/2个元素来尝试。(尝试是程序设计非常重要的方法,有时候即便我们不能一下子找到最优秀的解法,也能够在所尝试的解法中进行一步步的修改,接近最优解法。)

       此解法合理性分析:为了更加保守,我们选择A[k/2-1]与B[k/2-1]中的最小值来尝试,(这两个元素是作为分割子数组的标志),这里假设A[k/2-1]<=B[k/2-1]。                                                     

       我们来分析A[k/2-1]在和数组中的最大位置。这是个升序数组、顺序结构,一个元素的位置,通过与其它元素比较来确定。元素的最大下标,是小于或等于该元素的个数(因为有可能存在相同的元素)。                                                                                                                                         

       对与A[k/2-1],在A中有   k/2-1个元素小于或等于它,在B中最多有k/2-1个元素小于或等于它,所以在A+B中最多有k-2个元素小于或等于它,它在A+B中的最大下标是k-2,比第k个元素(下标为k-1)小。                                                                                                                                           

       我们舍弃A中的A[0]到A[k/2-1]元素不会舍弃掉目标值,符合二分法的要求。

四、程序设计中的循环端口。

        如何退出循环:我们可以大致预料到,随着舍弃元素过程的推进,最终会出现数组A或B中的元素被完全舍弃的情况。这时候就简化为了在一个数组中查找第k个元素的问题。

        如何处理bug:我们每次做的事情是 :                                                                                     

                                        (1)查找A和B中的k/2-1号元素。

                                        (2)比较这两个元素。

                                        (3)删去较小元素,及在其所在子数组中,比它小的元素。 

                                可能出现的bug:

                                        (1)越界:k==1 , k/2-1 == -1  这时只要返回min{A[0],B[0]} 

                                        (2)越界:k/2-1>m-1||k/2-1>n-1(m与n分别为每次操作中AB的大小)

                                                 这时只要将处理k/2-1号元素,改成处理m-1号元素即可。

                                             (假设没有越界,我们这样做相当于减少删去的元素,不用担   心误

                                                 删目标元素)

五、程序的异常处理。                                                                                                                       

       (1)数组不合法:m==0&&n==0; 

       (2)k不合法:k<1|| k>m+n;

六、程序的基本框架。                                                                                                                       

       1、判断m+n的奇偶。                                                                                                                 

       2、找第k个元素(分m+n奇偶情况讨论)                                                                                   

                 (1)异常处理。

                 (2)正常的循环:       

                          [1]判断是否到达循环端口:到达则输出。

                          [2]未到达则更新参数,推进循环(更新子数组与k:这里本人使用两个指针与     

                                                                                  vector<int>来表示一个数组的)

七、总结。                                                                                                                                         

       核心问题:如何设计一个循环程序。(计算机的优势是算力与内存,循环是发挥算力优势 的 

                                                                      一般方法)

       问题分析:(1)将问题先用通俗语言或者数学语言描述出来。                                                 

                         (2)将问题用计算机学科术语描述出来,查找、增删、数据处理等。                   

       建模:       (1)规划解决问题的基本思路,先将情况理想化,不考虑细节。(循环中间)     

                         (2)处理循环的端口问题。(循环开始与循环结束)                                             

                         (3)处理特殊情况。(数组访问越界)                                                                   

                         (4)异常处理。                                                                                                       

                         (5)调试与优化。       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值