leetCode - - - 二分查找

目录

1.二分查找(Leetcode 704)

2.搜索插入位置( LeetCode 35 )

3.寻找峰值(LeetCode 162)

4.旋转数组的最小数字(BM21)

5.总结


1.二分查找(Leetcode 704)

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: 
nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        //while(left < right): 这个条件会在 left 和 right 相邻时停止循环。
        //因此,当 left 和 right 相邻时,如果目标值恰好在 right 位置,循环将结束而不会进行最后一次检查。
        //所以要写left<=right
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid-1;
            }
        }
        return -1;
    }
}

2.搜索插入位置( LeetCode 35 )

https://leetcode.cn/problems/search-insert-position/description/

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4

和上一题相比,多了一步查找不到target插入,观察退出循环时:

因此,代码只是在二分查找的基础上多了一步返回到left下标。

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        //while(left < right): 这个条件会在 left 和 right 相邻时停止循环。
        //因此,当 left 和 right 相邻时,如果目标值恰好在 right 位置,循环将结束而不会进行最后一次检查。
        //所以要写left<=right
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid-1;
            }
        }
        return left;
    }
}

3.寻找峰值(LeetCode 162)

https://leetcode.cn/problems/find-peak-element/description/

峰值元素是指其值严格大于左右相邻值的元素。

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞ 。

你必须实现时间复杂度为 O(log n) 的算法来解决此问题

示例 1:

输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。

示例 2:

输入:nums = [1,2,1,3,5,6,4]输出:1 或 5 
解释:你的函数可以返回索引 1,其峰值元素为 2;
     或者返回索引 5, 其峰值元素为 6。

class Solution {
    public int findPeakElement(int[] nums) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int mid=left+(right-left)/2;
            if(nums[mid]<nums[mid+1]){
                left=mid+1;
            }else{
                right=mid;
            }
        }
        return left;
    }
}

4.旋转数组的最小数字(BM21)

https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=295&tqId=23269&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤n≤100001≤n≤10000,数组中任意元素的值: 0≤val≤100000≤val≤10000

要求:空间复杂度:O(1)O(1) ,时间复杂度:O(logn)O(logn)

示例1

输入:[3,4,5,1,2]

复制返回值:1

示例2

输入:[3,100,200,3]

复制返回值:3

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int minNumberInRotateArray (int[] nums) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int mid=left+(right-left)/2;
            if(nums[mid]>nums[right]){
                left=mid+1;
            }else if(nums[mid]<nums[right]){
                right=mid;
            }else{
                right--;
            }
        }
        return nums[left];
    }
}

5.总结

利用二分查找的分治策略,提高查找效率。
对于特定结构(如有序或旋转数组)的优化,减少时间复杂度到 O(logn)
动态调整搜索范围,依据当前状态决定下一步的方向。

二分查找(Leetcode 704):在有序数组中,通过二分查找快速定位目标值的索引。每次将搜索范围缩小一半,直到找到目标或范围为空。

搜索插入位置( LeetCode 35 ):在有序数组中,利用二分查找确定目标值的插入位置。通过比较目标值和中间值,调整搜索范围来找到插入点,保持数组有序。


寻找峰值(LeetCode 162):寻找局部峰值(比相邻元素大的元素)。通过二分查找逐步缩小范围,根据中间元素与其相邻元素的关系调整搜索方向,找到峰值。


旋转数组的最小数字(BM21):在旋转排序数组中,通过二分查找找到最小值。比较中间值与左右端点值,调整搜索范围以找到最小值,利用旋转数组的特点来决定方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Roylelele

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值