美文网首页
二分查找

二分查找

作者: lixwcqs | 来源:发表于2018-05-30 10:34 被阅读0次

    在一次面试中,让手写二分查找代码,
    我开始写了一个递归版,面试官让写了一个非递归版的,这个很快也写出来了,最后面试官有要求改进成求元素首次或者最后一次出现的位置,提示我稍微改动就可以实现,可惜当时没有写出来.

    package com.cqs.leetcode.ds.search;
    
    import com.cqs.leetcode.ds.ArraysUtils;
    import com.cqs.leetcode.ds.sort.ISort;
    import com.cqs.leetcode.ds.sort.MergeSort;
    
    import java.util.Random;
    
    /**
     * Author:li
     * <p>
     * create date: 18-5-30 09:27
     */
    public class BinarySearch {
    
    
        /**
         * 查询target在有序数组sort中首次出现的位置 若不存在返回-1
         *
         * @param sort
         * @param target
         * @return
         */
        public int searchFirst(int[] sort, int target) {
            if (sort == null || sort.length == 0) return -1;
            int left = 0, right = sort.length - 1, mid = (left + right) / 2;
            do {
                if (target == sort[mid]) {
                    //mid一定会大于等于left
                    if (mid == left || sort[mid - 1] != target) return mid;
                    right = mid - 1;
                } else if (target < sort[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
                mid = (left + right) / 2;
            } while (left <= right);
            return -1;
        }
    
        /**
         * 查询target在有序数组sort中最后一次出现的位置 若不存在返回-1
         *
         * @param sort
         * @param target
         * @return
         */
        public int searchLast(int[] sort, int target) {
            if (sort == null || sort.length == 0) return -1;
            int left = 0, right = sort.length - 1, mid = (left + right) / 2;
            do {
                if (target == sort[mid]) {
                    //mid一定会小于等于right
                    if (mid == right || sort[mid + 1] != target) return mid;
                    left = mid + 1;
                } else if (target < sort[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
                mid = (left + right) / 2;
            } while (left <= right);
            return -1;
        }
    
    
        /**
         * 基于循环实现二分查找
         *
         * @param sort
         * @param target
         * @return
         */
        public int search0(int[] sort, int target) {
            if (sort == null || sort.length == 0) return -1;
            int left = 0, right = sort.length - 1, mid = (left + right) / 2;
            do {
                if (target == sort[mid]) {
                    return mid;
                }
                if (target < sort[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
                mid = (left + right) / 2;
            } while (left <= right);
            return -1;
        }
    
        /**
         * 递归实现二分查找
         *
         * @param sort
         * @param target
         * @return
         */
        public int search(int[] sort, int target) {
            if (sort == null || sort.length == 0) return -1;
            return search(sort, 0, sort.length - 1, target);
        }
    
        private int search(int[] sort, int left, int right, int target) {
            if (left > right) return -1;
            int mid = (left + right) / 2;
            if (target == sort[mid]) {
                return mid;
            }
            if (target < sort[mid]) {
                return search(sort, left, mid - 1, target);
            }
            return search(sort, mid + 1, right, target);
        }
    
    
        public static void main(String[] args) {
            BinarySearch bs = new BinarySearch();
            ISort sort = new MergeSort();
            int[] nums = ArraysUtils.randInts(30);
    //        int[] nums = {0, 1, 2, 5, 5, 5, 6, 6, 7, 8};
            sort.sort(nums);
            //有序数组
            ArraysUtils.print(nums);
            int idx = new Random().nextInt(nums.length);
    //        idx = 5;
            int target = nums[idx];
            System.out.println("target:" + nums[idx]);
            System.out.println("index: " + idx + "\t" + bs.search(nums, target) + "\t" + bs.search0(nums, target)
                    + "\t首次位置:" + bs.searchFirst(nums, target) + "\t最后位置:" + bs.searchLast(nums, target));
        }
    }
    

    结果:


    image.png

    相关文章

      网友评论

          本文标题:二分查找

          本文链接:https://www.haomeiwen.com/subject/mdltsftx.html