华为OD机试真题【乱序整数序列两数之和绝对值最小】

news/2024/5/19 8:46:44 标签: 算法, java, 数据结构, 二分法, OD

1、题目描述

【乱序整数序列两数之和绝对值最小】
给定一个随机的整数(可能存在正整数和负整数)数组nums,请你在该数组中找出两个数,其和的绝对值(|nums[x]+nums[y1])为最小
值,并返回这个两个数(按从小到大返回)以及绝对值。
每种输入只会对应一个答案。
但是,数组中同一个元素不能使用两遍。
【输入描述】
一个通过空格分割的有序整数序列字符串,够1000个整数,且整数数值范围是[-65535, 65535]。
【输出描述】
两数之和绝对值最小值
【示例1】
【输入】

-1-37 511 15
【输出】
-352
说明
因为|nums[0] + nums[2]|=|-3+5|=2最小,所以返回-3 52。

2、解题思路

第一种方法是运用暴力递归的方式,依次将每两个数字求其和的绝对值,得到最小的一组即为答案。

两个数字的之和绝对值最小-定满足以下特征之-
●两个数字都负数,那么是最大的俩负数的和的绝对值最小。
●两个数字都是正数,那么是最小的俩整数的和的绝对值最小。
●一个数负数-个数是正数,此时情况需要特殊处理。因为需要绝对值最小,那么对于一个负数-N显然想找+N , 我们遇到一个负数x,要找非须数区的最接近于|x的的那个数。

所以解题思路了就很清晰了:将输入的整数数组排序Q,然后将问题转化为在数组的正数部分找到一个最接近给定负数的数的问题。这
样的问题可以通过二分查找来解决。从数组的负数部分开始遍历,然后在数组的正数部分使用一分查找找到一个最接近给定负数的正数。
后,我们需要比较所有可能情况得到的绝对值和,返回最小的一个。

3、参考代码

java">import java.util.Arrays;
import java.util.Scanner;

/**
 * @Author 
 * @Date 2023/6/11 23:15
 */
public class 乱序整数序列两数之和绝对值最小 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int[] nums = Arrays.stream(in.nextLine().split(" "))
                    .mapToInt(Integer::parseInt).toArray();

            getMinAbsSum(nums); // 方法一
            getMinAbsSum2(nums); // 方法二
        }
    }

    // 暴力解法
    public static void getMinAbsSum(int[] nums) {
        int min = Integer.MAX_VALUE;
        int[] minArr = new int[2];
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                int sum = Math.abs(nums[i] + nums[j]);
                if (sum < min) {
                    min = sum;
                    minArr[0] = nums[i];
                    minArr[1] = nums[j];
                }
            }
        }

        Arrays.sort(minArr);
        for (int arr : minArr) {
            System.out.print(arr + " ");
        }
        System.out.println(min);
    }

    public static void getMinAbsSum2(int[] nums) {
        Arrays.sort(nums);
        int munAbsSum = Integer.MAX_VALUE;
        int num1 = 0;
        int num2 = 0;

        if (nums[nums.length - 1] <= 0) {  // 全是负数
            num1 = nums[nums.length - 2];
            num2 = nums[nums.length - 1];
        } else if (nums[0] >= 0) {  // 全为正数
            num1 = nums[0];
            num2 = nums[1];
        } else {

            int zPos = findPos(nums);  // 找到第一个大于等于0的下标
            for (int i = 0; i < zPos; i++) {
                int j = findPos(nums, zPos, nums.length - 1, Math.abs(nums[i]));
                if (munAbsSum > Math.abs(nums[i] + nums[j])) {
                    munAbsSum = Math.abs(nums[i] + nums[j]);
                    num1 = nums[i];
                    num2 = nums[j];
                }
            }
        }

        System.out.println(num1 + " " + num2 + " " + Math.abs(num1 + num2));
    }

    // 找到第一个大于等于0的下标
    public static int findPos(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] >= 0) {
                return i;
            }
        }
        return -1;
    }

    // 找到接近k的位置
    public static int findPos(int[] arr, int left, int right, int k) {
        if (left > right) {
            return -1;
        }
        if (left == right) {
            return arr[left];
        }
        int j = left;
        while (left <= right) {
            int mid = left + ((right - left) / 2);
            if (arr[mid] <= k) {
                j = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        if (j == left) {
            return j;
        } else {
            return k - arr[j] <= k - arr[j + 1] ? j : j + 1;
        }
    }
}


http://www.niftyadmin.cn/n/5173513.html

相关文章

跨域的解决办法

单个控制器方法CORS注解 RestController RequestMapping("/system/test") public class TestController {CrossOriginGetMapping("/{id}")public AjaxResult getUser(PathVariable Integer userId) {// ...}DeleteMapping("/{userId}")public …

本地打包与云打包区别

香蕉云编&#xff1a;免费生成Ios、Android证书网址 云编-登录 1本地打包需要根据自己的需求去定制配置 - &#xff08;打包速度慢&#xff0c;可根据自己的需求进行定制&#xff09; 2云打包则更适合不需要定制项 - &#xff08;打包速度快&#xff09; 云打包&#xff08;Cl…

关于保留VLAN

1.定义 保留VLAN是作为交换机系统内部控制面通道以及部分特性的用户业务数据的承载通道。 是不是感觉有点晦涩难懂捏&#xff1f; 2.保留VLAN的ID范围 总范围&#xff1a;4064-4094 镜像口功能占用VLAN&#xff1a;4064-4071 后续拓展保留&#xff1a;4072-4094 系统占用…

Java常用设计模式(23种)

文章目录 介绍 设计模式的六大原则 一、创建型模式 1、单例模式&#xff08;Singleton Pattern&#xff09; 1&#xff09;饿汉式 2&#xff09;懒汉式&#xff0c;双检锁 3&#xff09;静态内部类 4&#xff09;枚举 2、原型模式&#xff08;Prototype Pattern&#xff09…

Zookeeper篇---第六篇

系列文章目录 文章目录 系列文章目录一、请简述Zookeeper的选主流程二、为什么Zookeeper集群的数目,一般为奇数个?三、知道Zookeeper监听器的原理吗?一、请简述Zookeeper的选主流程 Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做…

PostgreSQL 14.3 源码安装调试

摘要&#xff1a;介绍PostgreSQL 14.3 源码安装&#xff0c;postgresql使用和vscode源码调试。 1. 环境准备 1.1 系统参数修改 systemctl status firewalld.service #查看防火状态 systemctl stop firewalld.service #暂时关闭防火墙 systemctl disable firewalld.service …

Java的类与Golang的结构体的区别

Java作为一门面向对象&#xff08;OOP&#xff09;的编程语言&#xff0c;它有类&#xff08;class&#xff09;的存在&#xff0c;而对于Golang&#xff0c;它不完全遵从OOP编程语言的设计思想&#xff0c;但它也有类似Java类的结构存在&#xff0c;那就是结构体&#xff08;s…

mycat2 读写分离

mycat2 读写分离 mycat2 读写分离1.创建两个主从复制的数据库2.mycat2 读写分离3.mycat2读写分离测试 mycat2 读写分离 1.创建两个主从复制的数据库 参考&#xff1a;mysql主从复制 2.mycat2 读写分离 连接到mycat数据库 1.在mycat中创建数据库mydb1 CREATE DATABASE mydb…