1. 二分查找的题目
-
查找元素value的下标,如无 return -1
-
查找返回value(可能有重复)第一次出现的下标,如无return -1
-
查找返回value(可能有重复)最后一次出现的下标,如无return -1
-
查找返回刚好小于value的元素下标,如无return -1
-
查找返回刚好大于value的元素下标,如无return -1
2. 题解
2.1 查找元素value的下标
这个是基本的二分查找,直接上代码
public static int searchEqualValue(int[] nums,int val) {
if (nums == null || nums.length == 0) {
return -1;
}
int left = 0, right = nums.length, mid;
while (left < right) {
mid = (left + right) >> 1;
if ( val < nums[mid]) {
right = mid;
}else if (val > nums[mid]) {
left = mid + 1;
}else {
return mid;
}
}
return -1;
}
2.2 查找返回value(可能有重复)第一次出现的下标
判断 mid 对应值与 val 的 大小,如果 val 大, 则 left 设置为 mid + 1; 如果 val 小,则 right 设置 为 mid; 如果相等,则只能使right往前移动,这时还是 right 设置为 mid; while 条件是 left < right ,则最后退出循环时 left==right 的。
public static int searchFirstEqualValue(int[] nums,int val) {
if (nums == null || nums.length == 0) {
return -1;
}
int left = 0, right = nums.length, mid;
while(left < right) {
mid = (left+right) >> 1;
if(val > nums[mid]) {
left = mid+1;
}else if(val <= nums[mid]) {
right = mid;
}
}
return (left < nums.length && nums[left] == val)? left:-1;
}
2.3 查找返回value(可能有重复)最后一次出现的下标
public static int searchLastEqualValue(int[] nums,int val) {
if (nums == null || nums.length == 0) {
return -1;
}
int left = 0, right = nums.length, mid;
while(left + 1 < right) {
mid = (left+right) >> 1;
if(val >= nums[mid]) {
left = mid;
}else if(val < nums[mid]) {
right = mid;
}
}
return nums[left] == val? left:-1;
}
2.4 查找返回刚好小于value的元素下标
public static int searchLastLessThanValue(int[] nums, int val) {
if (nums == null || nums.length == 0) {
return -1;
}
/**
* nums中的元素都比val大于或者等于
*/
if (nums[0] >= val) {
return -1;
}
/**
* nums 中的元素都不val小
*/
if (nums[nums.length - 1] < val) {
return nums.length - 1;
}
int left = 0, right = nums.length, mid;
while(left + 1 < right) {
mid = (left+right) >> 1;
if(val > nums[mid]) {
left = mid;
}else if(val <= nums[mid]) {
right = mid;
}
}
return left;
}
2.5 查找返回刚好大于value的元素下标
public static int searchFirstGreaterThanValue(int[] nums, int val) {
if (nums == null || nums.length == 0) {
return -1;
}
/**
* nums中所有的值都 大于 val
*/
if (nums[0] > val) {
return 0;
}
/**
* nums中所有的值都 小于获取中等于 val
*/
if (nums[nums.length - 1] <= val) {
return -1;
}
int left = 0, right = nums.length, mid;
while(left + 1 < right) {
mid = (left+right) >> 1;
if(val >= nums[mid]) {
left = mid;
}else if(val < nums[mid]) {
right = mid;
}
}
return right;
}