1.二分查找
y总板子,这里是acwing二分查找的题解。分为两个板子
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int count = sc.nextInt();
int[] arr = new int[num];
for(int i = 0; i < num;i++){
arr[i] = sc.nextInt();
}
while(count-- > 0){
int target = sc.nextInt();
int l = 0, r = num -1;
while(l < r){
int mid = l + r >> 1;
if(arr[mid] >= target)
r = mid;
else
l = mid + 1;
}
if(arr[l] != target){
System.out.println("-1 -1");
}else{
System.out.print(l + " ");
l = 0 ; r = num - 1;
while(l < r){
int mid = l + r + 1 >> 1;
if(arr[mid] <= target)
l = mid ;
else
r = mid - 1;
}
System.out.println(l);
}
}
}
}
第一题,简单二分查找:力扣704
直接套用第一个板子,找不到时返回-1即可
class Solution {
public int search(int[] nums, int target) {
int l = 0, r = nums.length -1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target){
r = mid ;
}else{
l = mid + 1;
}
}
if(nums[l] != target) {
return -1;
}
return l;
}
}
第二题,搜索插入位置:力扣35
这里也是直接套用第一个板子,先判断目标是否比数组的数都大。
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0, r = nums.length - 1;
if(nums[r] < target){
return nums.length;
}
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target){
r = mid;
}else{
l = mid + 1;
}
}
return l;
}
}
第三题,在排序数组中查找元素的第一个和最后一个位置:力扣34
这题直接套用两个板子,完全符合y总的板子,但是需要注意特殊情况的处理:比如先判断是否为0;还有先判断第一个数是否为-1,如果是-1就直接返回
class Solution {
public int[] searchRange(int[] nums, int target) {
int len = nums.length;
if(len == 0){
return new int[]{-1,-1};
}
int f = first(nums,target);
if(f == -1){
return new int[]{-1,-1};
}
int la = end(nums,target);
return new int[]{f,la};
}
private int first(int[] nums, int target){
int l =0, r = nums.length -1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target){
r = mid;
}else{
l = mid + 1;
}
}
if(nums[l] != target){
return -1;
}
return l;
}
private int end(int[] nums,int target){
int l =0, r = nums.length -1;
while(l < r){
int mid = l + r + 1 >> 1;
if(nums[mid] <= target){
l = mid;
}else{
r = mid - 1;
}
}
return l;
}
}
第四题,x的平方根:力扣69
这种题型与前面的不一样,这种是套用第二个板子,而且这种题型是针对数进行二分,前面都是针对数组。
需要注意。在处理乘法时转换为除法。
class Solution {
public int mySqrt(int x) {
int l =0 , r = x;
while(l < r){
int mid = l + r + 1 >> 1;
if(mid <= x / mid){
l = mid;
}else{
r = mid - 1;
}
}
return l;
}
}
第五题,有效的完全平方数:力扣367
这个题跟上面的题差不多,遇到平方,平方跟,使用第二个板子即可
class Solution {
public boolean isPerfectSquare(int num) {
int l =0, r = num;
while(l < r){
int mid = l + r + 1 >> 1;
if(mid <= num / mid){
l = mid;
}else{
r = mid - 1;
}
}
return l * l == num ;
}
}
总结:平方数时使用第二个板子;求两个数时,两个板子一起使用。