二分查询

二分模板

/*
二分模板
 */
public class BinaryTemplate {
    public static void main(String[] args) {
        int[] nums=new int[]{1,2,3,4,5,6};
        int i = binarySearch(nums, 7);
        System.out.println(i);

    }

    /*
    nums是有序无重复的
     */
    public static int binarySearch(int[] nums,int target){
        int left=0;
        int right=nums.length-1;
        int mid=0;
        //保证计算到left==right的情况
        while (left<=right){
            //这么写防止数值越界
            mid=left+((right-left)>>1);

            if(nums[mid]>target){
                //不写right=mid为了防止死循环,与上面while条件配合
                right=mid-1;
            }else if(nums[mid]<target) {
                left=mid+1;
            }else if(nums[mid]==target){
                return mid;
            }

        }
        return -1;

    }
}

leetcode35

/*
https://leetcode-cn.com/problems/search-insert-position/
有序无重复数组插入位置问题

 */
public class searchInsert {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=left+((right-left)>>1);
            if(nums[mid]>target){
                right=mid-1;
            }else if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]==target){
                return mid;
            }
        }
       /*
       注意如果是无重复数组,如果没有找到,
        如果nums[mid]<target,则left=mid+1
        则nums[left]>target>nums[mid]=nums[right]
        如果nums[mid]>target,由于只有一个元素时left=mid,则
        nums[left]=nums[mid]>target>nums[mid-1]=nums[right]
        结论是nums[left]>target,nums[right]<target
         */
        return left;

    }

}

leetcode34

/*
有序数组的第一个元素位置和最后一个元素位置
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/submissions/
 */
//转换为有序数组的插入问题
public class searchRange {
    public int[] searchRange(int[] nums, int target) {
        int left=left(nums,target);
        int right=right(nums,target);
        int num[]=new int[]{-1,-1};
        if(left>right){
            return num;
        }
        num[0]=left;
        num[1]=right;
        return num;
    }

    //找到比target小的数x,并且靠近target,left是比这个数x大的位置
    public int left(int[] nums,int target){
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=left+((right-left)>>1);
            if(nums[mid]>=target){
                right=mid-1;
            }else if(nums[mid]<target){
                left=mid+1;
            }
        }
        return left;
    }

    //找到比target大的数x并且靠近target,right是比这个数x小的位置
    public int right(int[] nums,int target){
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=left+((right-left)>>1);
            if(nums[mid]<=target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid-1;
            }
        }
        return right;
    }
}

有序数组找出第一个大于目标元素的索引位置和找出第一个小于目标元素的索引位置

 public static void main(String[] args) {
        int nums[]={1,3,5,5,6,6,8,9,11};
        System.out.println(left1(nums, 3));


    }
    //找出第一个索引位置大于target的,转换为有序数组元素最后一个问题
    //例如3->2,11->-1,1->2
    public static  int right1(int[] nums,int target){
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=left+((right-left)>>1);
            if(nums[mid]<=target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return right+1>nums.length-1?-1:right+1;
    }


    //找出第一个索引位置小于target的数,转换为有序数组第一个元素问题
    //例如1->-1,11->7,3->0
    public static  int left1(int[] nums,int target){
        if(target<=nums[0]){
            return -1;
        }
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=left+((right-left)>>1);
            if(nums[mid]<target){
                left=mid+1;
            }else if (nums[mid]>=target){
                right=mid-1;
            }
        }
        return left-1<0?-1:left-1;
    }

非有序二分查询

旋转数组问题
leetcode33
查找旋转数组(无重复)元素索引

//https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
 public int search(int[] nums, int target) {
       int left=0;
       int right=nums.length-1;
       while (left<=right){
           int mid=left+((right-left)>>1);
           if(nums[mid]==target){
               return mid;
           }
           //左边有序的
           if(nums[mid]>=nums[left]){
               if(nums[mid]>target&&nums[left]<=target){
                   right=mid-1;
               }else{
                   left=mid+1;
               }
               //右边有序的
           }else if(nums[mid]<nums[left]){
               if(nums[mid]<target&&nums[right]>=target){
                   left=mid+1;
               }else{
                   right=mid-1;
               }
           }
       }
       return -1;
    }

leetcode81
查找旋转数组(有重复)元素索引

/*
    无序
    https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/
     */
    public boolean search2(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while (left<=right){
            int mid=left+((right-left)>>1);
            if(nums[mid]==target){
                return true;
            }
            if(nums[mid]>nums[left]){
                if(nums[mid]>target&&nums[left]<=target){
                    right=mid-1;
                }else{
                    left=mid+1;
                }
            }else if(nums[mid]<nums[left]){
                if(nums[mid]<target&&nums[right]>=target){
                    left=mid+1;
                }else{
                    right=mid-1;
                }
            }else if(nums[mid]==nums[left]){
                left++;
            }
        }
        return false;
    }

旋转数组最小值问题

//https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/
 public int findMin(int[] nums) {
       int left=0;
        int right=nums.length-1;
        //最小值有可能是nums[mid]
        int mid=0;
        int minmid=Integer.MAX_VALUE;
        while(left<=right){
            mid=left+((right-left)>>1);
            minmid=Math.min(minmid,nums[mid]);
            if(nums[left]<=nums[right]){
                return Math.min(nums[left],minmid);
            }
            if(nums[mid]>=nums[left]){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;

    }

二维数组的二分查询

//https://leetcode-cn.com/problems/search-a-2d-matrix/submissions/
 public boolean searchMatrix(int[][] matrix, int target) {
        int row=matrix.length;
        int col=matrix[0].length;
        int left=0;
        int right=row*col-1;
        while (left<=right){
            int mid=left+((right-left)>>1);
            int rownum=mid/col;
            int colnum=mid%col;
            if(matrix[rownum][colnum]==target){
                return true;
            }else if(matrix[rownum][colnum]<target){
                left=mid+1;
            }else if(matrix[rownum][colnum]>target){
                right=mid-1;
            }
        }
        return false;

    }

参考文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值