华为OD机试 - 最佳植树距离 - 二分查找(Java 2023 B卷 100分)

目录

一、题目描述

按照环保公司要求,小明需要在沙化严重的地区进行植树防沙工作,初步目标是种植一条直线的树带。

由于有些区域目前不适合种植树木,所以只能在一些可以种植的点来种植树木。 在树苗有限的情况下,要达到最佳效果,就要尽量散开种植,不同树苗之间的最小间距要尽量大。

给你一个适合种情树木的点坐标和一个树苗的数量,请帮小明选择一个最佳的最小种植间距。

例如,适合种植树木的位置分别为1,3,5,6,7,10,13 树苗数量是3,种植位置在1,7,13,树苗之间的间距都是6,均匀分开,就达到了散开种植的目的,最佳的最小种植间距是6。

二、输入描述

第1行表示适合种树的坐标数量。

第2行是适合种树的坐标位置。

第3行是树苗的数量。

三、输出描述

最佳的最小种植间距。

四、备注说明

位置范围为1~10000000

种植树苗的数量范围2~10000000

用例确保种植的树苗不会超过有效种植坐标数量

五、二分查找

二分查找(Binary Search),也称为折半查找,是一种在有序数组中查找特定元素的搜索算法。

二分查找的基本思想是将数组分成两部分,确定待查找元素可能存在的那一部分,然后继续对该部分进行二分,直到找到目标元素或者确定该元素不存在于数组中。

比如下面这段Java代码:

java 复制代码
public class BinarySearch {  
    public static int binarySearch(int[] array, int target) {  
        int left = 0;  
        int right = array.length - 1;  
  
        while (left <= right) {  
            int mid = (left + right) / 2;  
  
            if (array[mid] == target) {  
                return mid;  
            } else if (array[mid] < target) {  
                left = mid + 1;  
            } else {  
                right = mid - 1;  
            }  
        }  
  
        return -1;  
    }  
  
    public static void main(String[] args) {  
        int[] array = {1, 3, 5, 7, 9};  
        int target = 5;  
        int result = binarySearch(array, target);  
  
        if (result == -1) {  
            System.out.println("Element not found");  
        } else {  
            System.out.println("Element found at index " + result);  
        }  
    }  
}

在这个示例中,binarySearch方法接收一个有序数组array和要查找的目标元素target。然后,使用循环进行二分查找,将搜索范围不断缩小,直到找到目标元素或确定该元素不存在于数组中。如果找到目标元素,返回其索引,否则返回-1。

在main方法中,我们定义一个数组和一个目标元素,然后调用binarySearch方法并打印结果。

六、解题思路

  1. 第一行输入种树的坐标数量;
  2. 第二行输入树的坐标位置,通过java8 Stream表达式(简洁/方便/上档次)快速拆解输入行;
  3. 对树的坐标位置进行排序;
  4. 第三行输入树苗的数量;
  5. 通过二分查找进行比较;
  6. 取中间位置mid;
  7. 定义变量count,记录植树的总棵数;
  8. 取第一棵树的位置;
  9. 遍历树的坐标位置arr,并记录相对位置;
  10. 输出最佳的最小种植间距。

七、Java算法源码

java 复制代码
// 树的坐标位置
public static int[] arr;
// 树苗的数量
public static int num;

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);
    // 种树的坐标数量
    int n = Integer.valueOf(sc.nextLine());
    // 树的坐标位置
    arr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    // 树苗的数量
    num = Integer.valueOf(sc.nextLine());
    // 树的坐标位置排序
    Arrays.sort(arr);

    int min = arr[0];
    int max = arr[n - 1] - arr[0];
    // 通过二分查找进行比较
    while (min < max) {
        // 取中间位置
        int mid = (min + max) / 2;

        if (compare(mid)) {
            min = mid;
        } else {
            max = mid - 1;
        }
    }

    System.out.println(max);
}

public static boolean compare(int mid) {
    // 植树的总棵数
    int count = 1;
    // 第一棵树的位置
    int curPos = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] - curPos >= mid) {
            // 相距位置大于等于 mid,则可以种树
            count++;
            // 相对位置需要改变
            curPos = arr[i];
        }
    }

    return count >= num;
}

八、效果展示

1、输入

7

1 3 6 7 8 11 13

3

2、输出

6

3、说明

三颗树苗分别种在 1、7、13 的位置,可以保证种的最均匀,树苗之间的最小间距为 6。如果选择最小间距为 7,则无法种下3颗树苗。

🏆下一篇:华为OD机试真题 Java 实现【简易内存池】【2023 B卷 200分 考生抽中题】

🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

相关推荐
飛_36 分钟前
解决VSCode无法加载Json架构问题
java·服务器·前端
朝朝又沐沐3 小时前
算法竞赛阶段二-数据结构(36)数据结构双向链表模拟实现
开发语言·数据结构·c++·算法·链表
木棉软糖3 小时前
一个MySQL的数据表最多能够存多少的数据?
java
程序视点4 小时前
Java BigDecimal详解:小数精确计算、使用方法与常见问题解决方案
java·后端
愿你天黑有灯下雨有伞4 小时前
Spring Boot SSE实战:SseEmitter实现多客户端事件广播与心跳保活
java·spring boot·spring
薰衣草23334 小时前
一天两道力扣(6)
算法·leetcode
剪一朵云爱着4 小时前
力扣946. 验证栈序列
算法·
遇见尚硅谷4 小时前
C语言:*p++与p++有何区别
c语言·开发语言·笔记·学习·算法
Java初学者小白4 小时前
秋招Day20 - 微服务
java
天天开心(∩_∩)4 小时前
代码随想录算法训练营第三十二天
算法