zoukankan      html  css  js  c++  java
  • 二分查找的边界情况

    一、手写二分的几种边界情况

    1.普通查找值,找到即返回,不考虑位置

        //1.普通二分:查找数存不存在或者随便找一个
        public static int binarySearchOne(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                if( a[m]<target ){
                    l=m+1;
                }else if( a[m]>target ){
                    r=m-1;
                }else
                    return m;
            }
            return -1;
        }

    2.找第一个等于target的数

        //2.第一个等于target的数
        public static int firstEqual(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                //如果此时m是第一个等于target的数,r=m-1后不会再变了,等到l>r时就是第一个符合要求的元素
                if(a[m]>=target)
                    r=m-1;
                else
                    l=m+1;
            }
            //元素也可能不存在,需要先判断越界和符合情况
            if(l<n && a[l]==target)
                return l;
            return -1;
        }

    3.找第一个大于target的数

        // 3.找第一个大于target的数
        public static int binarySearchFirstMore(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                if( a[m]>target )
                    r=m-1;
                else
                    l=m+1;
            }
            return l>=n?-1:l;
        }

    4.找第一个大于等于目标值的数

        // 4.找第一个大于等于目标值的数
        public static int binarySearchFirstMoreEquals(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                if( a[m]>=target )
                    r=m-1;
                else
                    l=m+1;
            }
            return l>=n?-1:l;
        }

    5.找最后一个等于target的数

        // 5.找最后一个等于target的数
        public static int lastEqual(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                if(a[m]<=target)
                    l=m+1;
                else 
                    r=m-1;
            }   
            if(r>=0 && a[r]==target)
                return r;
            return -1;
        }

    6.找最后一个小于target的数

        // 6.找最后一个小于target的数
        public static int binarySearchLastLess(int target){
            int l=0,r=n-1,m;
            while(l<=r){
                m=(l+r)/2;
                if( a[m]<target )
                    l=m+1;
                else
                    r=m-1;
            }
            //如果r<0的话也是-1,不用判断了
            //return r<0?-1:r;
            return r;
        }

    7.找最后一个小于等于target的数

        // 7.找最后一个小于等于target的数
        public static int binarySearchLastLessEquals(int target){
            int l=0,r=n-1,m;
            while (l<=r){
                m=(l+r)/2;
                if( a[m]<=target )
                    l=m+1;
                else
                    r=m-1;
            }
            //如果r<0的话也是-1,不用判断了
            //return r<0?-1:r;
            return r;
        }

    8.用l+(r-l)/2替代(l+r)/2防止溢出

    9.总结

    (1)第一个...的情况最后返回的都是l,主要通过判断r的移动来操作

    • 寻找第一个等于target的,判断条件是if(a[m]>=target) r=m-1;最后判断l合法性以及是否存在;
    • 寻找第一个大于等于target的,判断条件也是if(a[m]>=target) r=m-1;
    • 寻找第一个大于target的,判断条件是if(a[m]>=target) r=m-1;

    (2)最后一个...的情况返回的都是r,主要通过判断l的移动来操作

    • 寻找最后一个等于target的,判断条件是if(a[m]<=target) l=m+1;最后判断r合法性以及是否存在;
    • 寻找最后一个小于等于target的,判断条件也是if(a[m]<=target) l=m+1;
    • 寻找最后一个小于target的,判断条件是if(a[m]<target) l=m+1;

    二、集合容器中的二分操作

    1.有序不重复集合TreeSet

    • boolean contains(Object o) 判断是否存在元素o
    • E ceiling(E e) 返回第一个大于或等于e的元素
    • E higher(E e) 返回第一个严格大于e的元素
    • E floor(E e) 返回第一个小于或等于e的元素
    • E lower(E e) 返回第一个严格小于e的元素

    如果以上方法没有找到元素,则返回null

    无序不重复集合HashSet没有后四个方法

    遍历集合

    for(E e:treeSet)

    2.有序不重复映射TreeMap

    • boolean contains(Object key) 判断是否存在键key
    • K ceilingKey(K key) 返回第一个大于或等于key的键
    • K higherKey(K key) 返回第一个严格大于key的键
    • K floorKey(K key) 返回第一个小于或等于key的键
    • K lowerKey(K key) 返回第一个严格小于key的键

    如果以上方法没有找到元素,则返回null

    无序不重复映射HashMap没有后四个方法

    遍历集合

    for (Map.Entry entry : treeMap.entrySet()) {
          System.out.println(entry);
    }

    三、推荐例题

  • 相关阅读:
    java设计模式
    漏桶算法工具类
    http请求requestUtils
    去掉字符串中特殊符号造成的空格
    java 分布式id生成算法
    java枚举
    java 32个Java面试必考点
    配置tomcat下war包可以自压缩
    tomcat (选号)公司tomcat无页面解决
    docker 12 docker容器数据卷
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/14619910.html
Copyright © 2011-2022 走看看