查找最接近的元素(最近不能相等)
描述
查找最接近的元素
输入
第一行包含一个整数n,为非降序列长度。1 <= n <= 100000。
第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000之间。
第三行包含一个整数m,为要询问的给定值个数。1 <= m <= 10000。
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000之间。
(注意:最接近但是不能相等。输入保证有解)
输出
m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。
若有多个值满足条件,输出最小的一个。
样例
3
2 5 8
2
10
5
8
2
难度
高
解法
要求找到与target最接近,但是不能相等的数,意味着要严格思考检查目标的左右边界最接近的值的位置。
lowerBound函数:在包含n个元素的、从小到大排序的int数组nums里查找比给定整数target小的,下标最大的元素。找到则返回其下标,找不到则返回-1------二分查找
upperBound函数:在包含n个元素的、从小到大排序的int数组nums里查找比给定整数target大的,下标最小的元素。找到则返回其下标,找不到则返回-1------二分查找
先判断target如果比第一个小,比最后一个大的情况,然后是分别有左右边界的情况,接着返回有左右边界中最接近的那个数。
代码
package com.company;
import java.util.*;
public class Main {
// 查找target小的,下标最大的元素
public static int lowerBound(long nums[],int n,long target){
int left = 0 , right = n;
int result = -1; //没找到
while(left<right){
int mid = (left + right)/2;
if(nums[mid]>=target) right=mid; //[left,mid)
else{
result = mid; //nums[mid]<target
left = mid+1;
}
}
if(result==-1&&nums[0]<target)
result = 0;
return result;
}
// 查找target小的,下标最小的元素
public static int upperBound(long nums[],int n,long target){
int left = 0 , right = n;
int result = -1; //没找到
while(left<right){
int mid = (left + right)/2;
if(nums[mid]<=target) left=mid+1;
else{
result = mid; //nums[mid]<target
right = mid;
}
}
if(result==-1&&nums[n-1]>target) //判断右边界
result = n-1;
return result;
}
public static void main(String[] args) {
int n,m,left,right;
long target,foundNumber;
Scanner input = new Scanner(System.in);
n = input.nextInt();
long[] numbers = new long[n];
for(int i=0;i<n;i++)
numbers[i] = input.nextLong();
m = input.nextInt();
while(m>0){
m--;
target = input.nextLong();
if(target<numbers[0]){
System.out.println(numbers[0]);
continue;
}
if(target>numbers[n-1]){
System.out.println(numbers[n-1]);
continue;
}
left = lowerBound(numbers,n,target);
right = upperBound(numbers,n,target);
if(left==-1){
System.out.println(numbers[right]);
continue;
}
if(right==-1){
System.out.println(numbers[left]);
continue;
}
foundNumber = target-numbers[left]>numbers[right]-target?numbers[right]:numbers[left];
System.out.println(foundNumber);
}
}
}
来源:CSDN
作者:马踏飞燕&lin_li
链接:https://blog.csdn.net/matafeiyanll/article/details/104859990