【代码+详解】算法题 : 查找最接近的元素

❗❗❗必看:
下列题我全部都使用 Java 语言写的,并且均可以提交成功,获得Accepted 结果的. 如果代码和详解看了之后,对答案有任何疑问,都可以在评论区提出来,我都会一个一个回答.

❗❗❗感谢大家的支持,如果喜欢我的博客,关注 点赞 收藏 评论一波,非常感谢!!!

题目:查找最接近的元素

在一个非降序列中,查找与给定值最接近的元素。

Input

第一行包含一个整数n,为非降序列长度。1 <= n <= 100000。
第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。
第三行包含一个整数m,为要询问的给定值个数。1 <= m <= 10000。
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。

Output

m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。

样例测试

输入

3
2 5 8
2
10
5

输出

8
5

代码

import java.util.Arrays;
import java.util.Scanner;

public class Main {

	    public static void main(String[] args) {
	        Scanner sc = new Scanner(System.in);
	        
	        // 读取非降序列长度
	        int n = sc.nextInt();
	        int[] arr = new int[n];
	        
	        // 读取非降序列
	        for (int i = 0; i < n; i++) {
	            arr[i] = sc.nextInt();
	        }
	        
	        // 读取查询个数
	        int m = sc.nextInt();
	        int[] queries = new int[m];
	        
	        // 读取每个查询值
	        for (int i = 0; i < m; i++) {
	            queries[i] = sc.nextInt();
	        }
	        
	        // 使用StringBuilder减少I/O操作次数
	        StringBuilder sb = new StringBuilder();
	        
	        // 处理每个查询并输出结果
	        for (int i = 0; i < m; i++) {
	            sb.append(findClosest(arr, queries[i])).append("\n");
	        }
	        
	        // 输出所有结果
	        System.out.print(sb.toString());
	        
	        sc.close();
	    }
	    
	    public static int findClosest(int[] arr, int target) {
	        int pos = Arrays.binarySearch(arr, target);
	        
	        if (pos >= 0) {
	            // 目标值在数组中,直接返回
	            return arr[pos];
	        } else {
	            // 目标值不在数组中,计算插入点
	            int insertionPoint = -pos - 1;
	            if (insertionPoint == 0) {
	                // 插入点在数组起始位置,返回第一个元素
	                return arr[0];
	            } else if (insertionPoint == arr.length) {
	                // 插入点在数组末尾,返回最后一个元素
	                return arr[arr.length - 1];
	            } else {
	                // 插入点在数组中间,比较前后元素
	                int before = arr[insertionPoint - 1];
	                int after = arr[insertionPoint];
	                if (Math.abs(before - target) <= Math.abs(after - target)) {
	                    return before;
	                } else {
	                    return after;
	                }
	            }
	        }
	    }
	}

初步思路

利用二分查找快速定位目标值在非降序列中的位置,找到最接近的元素。

具体步骤

  1. 读取输入

    • 首先读取非降序列的长度 n。
    • 然后读取非降序列的 n 个元素。
    • 接着读取查询的个数 m。
    • 最后读取 m 个查询值。
  2. 使用二分查找

    • 对于每个查询值 target,使用 Arrays.binarySearch(arr, target) 在非降序列中进行二分查找。
  3. 处理二分查找结果

    • 如果找到目标值,直接返回该值。
    • 如果未找到,Arrays.binarySearch 返回负的插入点位置 -pos-1。
    • 根据插入点位置确定最接近的元素:
      • 如果插入点位置为 0,返回数组的第一个元素。
      • 如果插入点位置在数组末尾,返回数组的最后一个元素。
      • 否则,比较插入点前后的两个元素,返回距离目标值较近的元素(若距离相同,返回较小的元素)。
  4. 输出结果

    • 将每个查询的结果存入 StringBuilder 中,最后一次性输出所有结果以减少 I/O 操作。

总结方法

这个方法通过利用二分查找的特性高效定位目标值的位置,并根据插入点前后的元素进行比较,确保找到最接近的值。通过减少 I/O 操作,提高了整体的运行效率。这种方法在处理大规模数据时尤为有效,体现了算法优化的重要性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值