二分模板
/*
二分模板
*/
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;
}