美文网首页
「力扣」第 704 题:二分查找

「力扣」第 704 题:二分查找

作者: 李威威 | 来源:发表于2020-01-27 19:26 被阅读0次

    地址:https://leetcode-cn.com/problems/binary-search/

    原始二分查找实现:循环

    Java 代码:

    public class Solution {
    
        public int search(int[] nums, int target) {
            int len = nums.length;
            if (len == 0) {
                return -1;
            }
            // 在 [left, right] 区间里查找 target
            int left = 0;
            int right = len - 1;
            while (left <= right) {
    
                int mid = (left + right) / 2;
    
                if (nums[mid] == target) {
                    return mid;
                } else if (nums[mid] > target) {
                    // 下一轮搜索区间:[left, mid - 1]
                    right = mid - 1;
                } else {
                    // 此时:nums[mid] < target
                    // 下一轮搜索区间:[mid + 1, right]
                    left = mid + 1;
                }
            }
            return -1;
        }
    }
    

    原始二分查找实现:递归

    Java 代码:

    public class Solution {
    
        public int search(int[] nums, int target) {
            int len = nums.length;
            if (len == 0) {
                return -1;
            }
            return binarySearch(nums, target, 0, len - 1);
        }
    
        /**
         * 在数组 arr 的子区间 [left, right] 里搜索目标元素
         *
         * @param arr    数组
         * @param target 目标元素
         * @param left   左边界索引,包括 left
         * @param right  右边界索引,包括 right
         * @return
         */
        private int binarySearch(int[] arr, int target, int left, int right) {
            // 先处理递归到底的情况
            if (left > right) {
                // 不能形成区间,返回 -1 表示没有找到
                return -1;
            }
            int mid = (left + right) / 2;
            if (target == arr[mid]) {
                // 找到了,就将目标元素的索引返回
                return mid;
            } else if (target < arr[mid]) {
                // 既然是有序数组,目标元素的值比中间元素还要小,就应该在中间元素的左边去找
                return binarySearch(arr, target, left, mid - 1);
            } else {
                // 既然是有序数组,目标元素的值比中间元素还要大,就应该在中间元素的右边去找
                return binarySearch(arr, target, mid + 1, right);
            }
        }
    }
    

    “减治法”二分查找

    把等于元素放在最后判断的二分查找算法。

    注意:看到 left = mid; 取中间数的时候要加 1

    • 实现 1:

    Java 代码:

    public class Solution {
    
        public int search(int[] nums, int target) {
            int len = nums.length;
    
            int left = 0;
            int right = len - 1;
    
            while (left < right) {
                // 注意:根据分支逻辑,需要在取中间数的时候,向上取整
                int mid = (left + right + 1) >>> 1;
    
                if (nums[mid] > target) {
                    // 下一轮搜索区间是:[left, mid - 1]
                    right = mid - 1;
                } else {
                    // 此时 nums[mid] <= target
                    // mid 的左边一定不等于目标元素
                    // 下一轮搜索区间是:[mid, right]
                    left = mid;
                }
            }
            // 不要忘了单独做判断
            if (nums[left] == target) {
                return left;
            }
            return -1;
        }
    }
    
    • 实现 2:

    Java 代码:

    public class Solution {
    
        public int search(int[] nums, int target) {
            int len = nums.length;
            int left = 0;
            int right = len - 1;
            while (left < right) {
    
                int mid = (left + right) >>> 1;
    
                if (nums[mid] < target) {
                    // 下一轮搜索区间是:[mid + 1, right]
                    left = mid + 1;
                } else {
                    // 此时 nums[mid] >= target,
                    // mid 的右边一定不存在 target,下一轮搜索区间是:[left, mid]
                    right = mid;
                }
            }
            // 不要忘了单独做判断
            if (nums[left] == target) {
                return left;
            }
            return -1;
        }
    }
    

    相关文章

      网友评论

          本文标题:「力扣」第 704 题:二分查找

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