• 二分查找模版


    二分查找模版

    • 来源:公众号 labuladong

    • 注意: int mid = left + (right - left) / 2; 这么写而不是 int mid = (left + right) >> 1; 是由于left加right可能整数溢出

    public class BinarySearch {
        
        ////找到nums数组中的一个和target值相同的位置,未找到则返回-1(适用于非重复值数组)
        int binary_search(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while(left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if(nums[mid] == target) {
                    // 直接返回
                    return mid;
                }
            }
            // 直接返回
            return -1;
        }
    
        //找到nums数组中最左边一个和target值相同的位置,未找到则返回-1,(适用于重复值数组)
        int left_bound(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    // 别返回,收缩左侧边界
                    right = mid - 1;
                }
            }
            // 最后要检查 left 越界的情况
            if (left >= nums.length || nums[left] != target)
                return -1;
            return left;
        }
    
    
        //找到nums数组中最右边一个和target值相同的位置,未找到则返回-1,(适用于重复值数组)
        int right_bound(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    // 别返回,收缩右侧边界
                    left = mid + 1;
                }
            }
            // 最后要检查 right 越界的情况
            if (right < 0 || nums[right] != target)
                return -1;
            return right;
        }
        
    }
    • 例题:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/

    public class P34FindFirstAndLastPositionOfElementInSortedArray {
        /**
         * 输入: nums = [5,7,7,8,8,10], target = 8
         * 输出: [3,4]
         */
        public static void main(String[] args) {
            Solution solution = new P34FindFirstAndLastPositionOfElementInSortedArray().new Solution();
            // TO TEST
            int[] ints = solution.searchRange(new int[]{5, 7, 7, 8, 8, 10}, 8);
            for (int anInt : ints) {
                System.out.print(anInt + ",");
            }
        }
    
        //leetcode submit region begin(Prohibit modification and deletion)
        class Solution {
            public int[] searchRange(int[] nums, int target) {
    
                int[] arr = new int[]{-1, -1};
                int len = nums.length;
                if (len == 0) {
                    return arr;
                }
    
                arr[0] = left_bound(nums, target);
                arr[1] = right_bound(nums, target);
                return arr;
            }
    
            //找到nums数组中最左边一个和target值相同的位置,未找到则返回-1,(适用于重复值数组)
            int left_bound(int[] nums, int target) {
                int left = 0, right = nums.length - 1;
                while (left <= right) {
                    int mid = left + (right - left) / 2;
                    if (nums[mid] < target) {
                        left = mid + 1;
                    } else if (nums[mid] > target) {
                        right = mid - 1;
                    } else if (nums[mid] == target) {
                        // 别返回,收缩左侧边界
                        right = mid - 1;
                    }
                }
                // 最后要检查 left 越界的情况
                if (left >= nums.length || nums[left] != target)
                    return -1;
                return left;
            }
    
    
            //找到nums数组中最右边一个和target值相同的位置,未找到则返回-1,(适用于重复值数组)
            int right_bound(int[] nums, int target) {
                int left = 0, right = nums.length - 1;
                while (left <= right) {
                    int mid = left + (right - left) / 2;
                    if (nums[mid] < target) {
                        left = mid + 1;
                    } else if (nums[mid] > target) {
                        right = mid - 1;
                    } else if (nums[mid] == target) {
                        // 别返回,收缩右侧边界
                        left = mid + 1;
                    }
                }
                // 最后要检查 right 越界的情况
                if (right < 0 || nums[right] != target)
                    return -1;
                return right;
            }
        }
    }
  • 相关阅读:
    万能的everything彻底解决mysql问题
    乱码问题
    机器学习学习规划
    NG机器学习笔记
    书籍与博客
    技术规划
    反置数
    多个接口出现同名函数的处理-转
    接口-imploements-委托
    接口使用中,对象生命周期管理-转
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/12801664.html
Copyright © 2020-2023  润新知