LeeCode算法题:二分查找

文章目录

  • 二分查找算法原理
  • 题1:二分查找
    • 代码实现
  • 题2:二维数组中的查找
    • 代码实现
  • 题3:寻找峰值元素
    • 代码实现
  • 参考


二分查找算法原理

  • 二分查找又叫折半查找,优点是查找速度快,平均性能好,算法时间的复杂度为O(logn);缺点是要求待查表为有序表,且插入删除困难,因此这种查找方法适用于不经常变动而查找频繁的有序列表。
  • 二分查找算法如下:
  • 输入:待查列表array,目标元素target
  • 1、如果array为空,则返回-1,退出算法,-1表示查找不到target;
  • 2、如果array不为空,则比较中间元素与target是否相等,如果相等,则返回该中间元素的索引,并退出算法;否则比较这俩元素的大小;
  • 3、如果该中间元素大于target,那么target应该位于列表的前半部分,因此将列表前半部分作为待查找的列表;
  • 4、如果该中间元素小于target,那么target应该位于列表的后半部分,因此将列表后半部分作为待查找的列表;
  • 5、针对新的待查列表,重新从步骤1开始。

题1:二分查找

题目描述:请实现无重复数字的升序数组的二分查找。
示例:
输入:[-1,0,3,4,6,10,13,14],13
输出:6

代码实现

import java.util.*;
public class Solution {
    public int search (int[] nums, int target) {
        // 通过定义左右边界,定义待查找列表
        int left = 0, right = nums.length-1;
        int mid = (left+right)/2;
        //当左边界大于右边界,终止
        while(left<=right){
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid]>target){
                right = mid-1;
            }else{
                left = mid+1;
            }
            mid = (left+right)/2;
        }
      return -1;  
    }   
}

题2:二维数组中的查找

题目描述:在一个二维数组中,每一行递增排序,每一列递增排序,给定一个整数,判断该二维数组中是否含有该整数。
示例:
输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
输出:true

代码实现

//可以利用二维数组行列递增特性,从二维数组右上角出发进行判断,如果大于目标元素,那么应该向左搜索寻找;
//如果小于目标元素,应该向下寻找
public class Solution {
    public boolean Find(int target, int [][] array) {
        int m = array.length;
        int n = array[0].length;
        int row = 0, col = n-1;
        while(row<m && col>=0){
            if(array[row][col]>target){
                col -= 1;
            } else if(array[row][col]<target){
                row += 1;
            } else{
                return true;
            }
        }
        return false;
    }
}

题3:寻找峰值元素

题目描述:给定一个长度为n的数组,请找到峰值元素的索引并返回。峰值元素是指其值严格大于左右相邻值的元素,即不能等于。数组可能包含多个峰值,可任意返回一个位置即可。假设nums[-1] = nums[n] = 负无穷。
示例:
输入:[2,4,1,2,7,8,4]
输出:1(4和8都是峰值元素,返回索引1和索引5都可以)

代码实现

// 容易理解的一种方法:顺序遍历数组,并设置一个元素递增的检查标志,
//当下一个元素大于当前元素时,将标志置位true,并获得可能的峰值索引
// 当小于下一个元素时,表明开始出现下降,此时若递增标志为true,则表明遇到了峰值,跳出循环,返回峰值索引
public class Solution {
    public int findPeakElement (int[] nums) {
        boolean increase_checking = false;
        int peek_index = 0;
        for(int i=0;i<nums.length-1;i++){
            if(nums[i] < nums[i+1]){
                increase_checking = true;
                peek_index = i+1;
            }else if(nums[i]>nums[i+1] && increase_checking){
                break;
            }
        }
        return peek_index;
    }
}
// 还有一种是采用二分查找,我觉得不容易理解
// 简单的解释:为找到一个局部的峰值,我们每次将搜索范围缩小一半,这一半确保了峰值的一个边界条件成立,而另一半是不成立的
// 但是,当最终减少到一个数字的时候,此时单个数的两个峰值边界条件都满足了
public class Solution {
    public int findPeakElement (int[] nums) {
        int left = 0,right = nums.length-1;
        int mid = (left+right)/2;
        while(left<right){
        // 当大于下一个元素时,我们选择在左边查找
        // 否则,在右边查找
            if(nums[mid]>nums[mid+1]){
                right = mid;
            } else {
                left = mid+1;
            }
            mid = (left+right)/2;
        }
        return left;
}

参考

https://www.jianshu.com/p/99257a99e6d5
如有侵权,请联系作者删除

你可能感兴趣的:(python,算法,java)