@Test
public void testBinSearch() {
int[] i = {1, 3, 5, 6, 8};
int[] r1 = {bS1(i, 0), bS1(i, 1), bS1(i, 3), bS1(i, 6), bS1(i, 8), bS1(i, 9)};
System.out.println(Arrays.toString(r1));
System.out.println("--------------------");
int[] r2 = {bS2(i, 0), bS2(i, 1), bS2(i, 3), bS2(i, 6), bS2(i, 8), bS2(i, 9)};
System.out.println(Arrays.toString(r2));
System.out.println("--------------------");
int[] r3 = {bS3(i, 0), bS3(i, 1), bS3(i, 3), bS3(i, 6), bS3(i, 8), bS3(i, 9)};
System.out.println(Arrays.toString(r3));
System.out.println("--------------------");
int[] r4 = {bS4(i, 0), bS4(i, 1), bS4(i, 3), bS4(i, 6), bS4(i, 8), bS4(i, 9)};
System.out.println(Arrays.toString(r4));
}
public int bS1(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
// 终止条件[right + 1, right],此时搜索区间为空
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
if (nums[mid] < target) left = mid + 1;
if (nums[mid] > target) right = mid - 1;
}
return -1;
}
public int bS2(int[] nums, int target) {
int left = 0;
int right = nums.length; // 右边界初始为length,取不到
// 终止条件[right, right],此时搜索区间非空,但右边界不可能为target
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
if (nums[mid] < target) left = mid + 1;
if (nums[mid] > target) right = mid; // right边界永远不可能为target,不需要对结果打补丁
}
return -1;
}
public int bS3(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 右边界初始为最后一个元素
// 终止条件[right, right],此时搜索区间非空,且右边界可能为target,需要对单独最后一个元素进行判断
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
if (nums[mid] < target) left = mid + 1;
if (nums[mid] > target) right = mid - 1; // right边界有可能为target,需要对结果打补丁
}
return nums[left] == target ? left : -1;
}
public int bS4(int[] nums, int target) {
int left = 0;
int right = nums.length; // 右边界初始为length,有可能有边界从始至终都没有变化,需要单独处理
// 终止条件[right, right],此时搜索区间非空,且右边界可能为target,需要对单独最后一个元素进行判断
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
if (nums[mid] < target) left = mid + 1;
if (nums[mid] > target) right = mid - 1; // right边界有可能为target,需要对结果打补丁
}
if (right == nums.length) return -1;
return nums[left] == target ? left : -1;
}
@Test
public void testBinSearchPlus() {
int[] nums = {1, 2, 2, 2, 3};
int[] r1 = {bSL(nums, 0), bSL(nums, 1), bSL(nums, 2), bSL(nums, 3), bSL(nums, 4)};
System.out.println(Arrays.toString(r1));
System.out.println("-----------------");
int[] r2 = {bSR(nums, 0), bSR(nums, 1), bSR(nums, 2), bSR(nums, 3), bSR(nums, 4)};
System.out.println(Arrays.toString(r2));
}
// 最左侧的target
public int bSL(int[] nums, int target) {
int left = 0;
int right = nums.length;
while (left < right) { // 结束条件left == right
int mid = left + ((right - left) >> 1);
if (nums[mid] >= target) right = mid; // 右边界可能为target
if (nums[mid] < target) left = mid + 1; // 左边界依次逼近右边界
}
if (left == nums.length) return -1;
return nums[left] == target ? left : -1;
}
// 最右侧的target
public int bSR(int[] nums, int target) {
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] <= target) left = mid + 1; // 左边界的左侧可能为target
if (nums[mid] > target) right = mid;
}
if (left == 0) return -1;
return nums[left - 1] == target ? left - 1 : -1;
}