LeetCode之二分查找

35. 搜索插入位置

class Solution {

    public int searchInsert(int[] nums, int target) {
        // 定义左指针,指向数组起始位置
        int left = 0;
        // 定义右指针,指向数组末尾位置
        int right = nums.length - 1;
        // 定义边界,用于找出不存在的值要插入的位置,初始值为数组长度,即插入到数组末尾之后
        int ans = nums.length;
        // 当左指针小于等于右指针时进行循环,确保搜索区间存在
        while(left <= right) {
            // 计算中间位置,使用 (right - left) / 2 + left 可以避免整数溢出
            int mid = (left + right) / 2;
            if (target <= nums[mid]) {
                // 如果目标值小于等于中间位置的值,说明目标值可能在左半部分
                right = mid - 1;
                // 更新答案为中间位置,因为目标值可能插入在中间位置
                ans = mid;
            } else {
                // 如果目标值大于中间位置的值,说明目标值可能在右半部分
                left = mid + 1;
            }
        }
        // 返回目标值应插入的位置
        return ans;
    }

}

74. 搜索二维矩阵

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // 矩阵的行数
        int m = matrix.length;
        // 矩阵的列数
        int n = matrix[0].length;
        // 搜索区间的下界
        int low = 0;
        // 搜索区间的上界
        int high = m * n - 1;

        while (low <= high) {
            // 计算中间位置
            int mid = (low + high) / 2;
            // 通过 mid / n 得到中间位置对应的行索引,mid % n 得到列索引
            // 用索引除以列数n可以得到行索引;而索引对列数取余可以得到在当前行中的列索引
            if (target < matrix[mid / n][mid % n]) {
                // 如果目标值小于中间位置的值,更新上界为 mid - 1
                high = mid - 1;
            } else if (target > matrix[mid / n][mid % n]) {
                // 如果目标值大于中间位置的值,更新下界为 mid + 1
                low = mid + 1;
            } else {
                // 如果目标值等于中间位置的值,说明找到了目标,返回 true
                return true;
            }
        }
        // 循环结束后仍未找到目标,返回 false
        return false;
    }
}

162. 寻找峰值

class Solution {

    public int findPeakElement(int[] nums) {
        // 初始化一个索引变量,用于存储当前找到的峰值元素的索引
        int index = 0;

        // 遍历数组中的每个元素
        for (int i = 0; i < nums.length; i++) {
            // 如果当前元素大于当前记录的峰值元素
            if (nums[i] > nums[index]) {
                // 更新峰值元素的索引为当前元素的索引
                index = i;
            }
        }
        // 返回峰值元素的索引
        return index;
    }
}

33. 搜索旋转排序数组

public class Solution {
    public int search(int[] nums, int target) {
        // 定义left指针,指向数组的最左端
        int left = 0;
        // 定义right指针,指向数组的最右端
        int right = nums.length - 1;

        while (left <= right) {
            // 右移 1 相当于除以 2,计算中间位置
            int mid = (left + right) >> 1;
            // 如果中间位置的值等于目标值,直接返回中间位置的索引
            if (target == nums[mid]) {
                return mid;
            }
            // 左半部分为顺序区间
            if (nums[left] <= nums[mid]) {
                // 如果目标值大于等于左指针指向的值且小于中间值
                if (target >= nums[left] && target < nums[mid]) {
                    // 在左半部分继续查找,更新右指针为 mid - 1
                    right = mid - 1;
                } else {
                    // 否则在右半部分查找,更新左指针为 mid + 1
                    left = mid + 1;
                }
            // 右半部分为顺序区间
            } else {
                // 如果目标值大于中间值且小于右指针指向的值
                if (target > nums[mid] && target <= nums[right]) {
                    // 在右半部分继续查找,更新左指针为 mid + 1
                    left = mid + 1;
                } else {
                    // 否则在左半部分查找,更新右指针为 mid - 1
                    right = mid - 1;
                }
            }
        }
        // 如果没有找到目标值,返回 -1
        return -1;
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置

class Solution {

    public int[] searchRange(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int first = -1;
        int last = - 1;

        while (left <= right) {
            int mid = (right - left) / 2 + left;

            if (target < nums[mid]) {
                right = mid - 1;
            } else if (target > nums[mid]) {
                left = mid + 1;
            } else {
                first = mid;
                right = mid - 1;
            }
        }

        left = 0;
        right = nums.length - 1;

        while (left <= right) {
            int mid = (right - left) / 2 + left;

            if (target < nums[mid]) {
                right = mid - 1;
            } else if (target > nums[mid]) {
                left = mid + 1;
            } else {
                last = mid;
                left = mid + 1;
            }
        }

        return new int[]{first, last};
    }

}

153. 寻找旋转排序数组中的最小值

class Solution {
    public int findMin(int[] nums) {
        // 定义左指针,指向数组起始位置
        int left = 0;
        // 定义右指针,指向数组末尾位置
        int right = nums.length - 1;
        // 先将答案初始化为数组第一个元素
        int ans = nums[0];

        while (left <= right) {
            // 计算中间位置
            int mid = (left + right) >> 1;
            // 如果左指针指向的元素小于等于中间位置的元素
            if (nums[left] <= nums[mid]) {
                // 更新答案为当前左指针指向元素和已有答案中的较小值
                ans = Math.min(ans, nums[left]);
                // 说明最小值在右侧区间,左指针向右移动
                left = mid + 1;
            } else {
                // 更新答案为当前中间位置元素和已有答案中的较小值
                ans = Math.min(ans, nums[mid]);
                // 说明最小值在左侧区间,右指针向左移动
                right = mid - 1;
            }
        }

        return ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值