华为OD机试 - 奇偶三数之和(Java 新系统 100分)

【华为OD】2024年华为OD机试C卷、D卷真题集:最新的真题集题库 C/C++/Java/python/JavaScript 2024年华为OD机试C卷真题题集题库,有2种分数的题目列表分别是100分的列表、200分的列表从2023年11月开始,华为OD题目切换到C卷,基本上大概率会使用半年左右,要在2024年5月之前把这些题目都好好练习一下,可以得到很好的收获,基本上都是出的原题,提前恭喜大家都上岸。目前通过大大提供的真题练习,已经有上百人成功上岸了,而且大大还是一个老师,通过大大指导进入华为OD的学生已经有上千人了。 2024年5月之前,碰到原题的概率是98%以上。 阅读详情

在这里插入图片描述

华为OD机试 新系统 题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天优快云在线答疑。

一、题目描述

给定一个包含 n n n 个整数的数组 nums 和一个整数 target,请从数组中找出所有 不重复 的三元组 [nums[i], nums[j], nums[k]],满足以下两个条件:

  1. 和为目标:

    n u m s [ i ] + n u m s [ j ] + n u m s [ k ] = t a r g e t nums[i] + nums[j] + nums[k] = target nums[i]+nums[j]+nums[k]=target

  2. 奇偶性约束:

    三个元素中 至少有两个 是奇数。

    返回所有满足条件的不重复三元组。

    提示:

  • 3 ≤ n u m s . l e n g t h ≤ 3000 3 \le nums.length \le 3000 3≤nums.length≤3000

  • − 10 5 ≤ n u m s [ i ] ≤ 10 5 -10^5 \le nums[i] \le 10^5 −105≤nums[i]≤105

    补充说明

    返回值输出格式:每个子数组内部的元素按数值升序排列,所有子数组之间按字典序升序排列(即先比较第一个元素,若相同再比较第二个,以此类推)。

    示例:[[-1,-1,2],[-1,0,1]]

二、输入描述

输入为一个数组 nums 和一个目标整数 target。

三、输出描述

输出所有满足条件的不重复三元组。

四、测试用例

测试用例1:

1、输入

-1,0,1,2,-1,-4
0

2、输出

-1,-1,2
-1,0,1

3、说明

两个三元组都满足和为 0,并且至少两个元素为奇数。

测试用例2:

1、输入

1,2,3,4,5
9

2、输出

1,3,5

3、说明

2,3,4 虽然和为 9,但只有 3 一个奇数,因此排除。

五、解题思路

本题本质上是在经典“三数之和”问题上增加了两个要求:三元组不能重复,并且三个元素中至少有两个奇数。

首先对数组进行升序排序。排序有三个作用:第一,每个找到的三元组天然满足内部元素升序;第二,相同数字会排列在一起,可以通过跳过重复元素完成去重,不需要额外使用 HashSet;第三,排序后可以使用双指针,将原本三层循环的 O(n³) 时间复杂度优化为 O(n²)。

具体做法是枚举三元组中的第一个元素 nums[i]。如果 nums[i] 与前一个元素相同,则直接跳过,避免产生重复答案。随后令 left=i+1、right=n-1,计算 nums[i]+nums[left]+nums[right]。如果和小于 target,说明需要增大总和,因此 left++;如果和大于 target,则 right–;如果正好等于 target,再统计三个元素中的奇数数量。奇数个数不少于 2 时,将当前三元组加入结果。

当找到一个和等于 target 的组合后,无论其是否通过奇偶性检查,都需要跳过 left 和 right 位置上的重复值,因为相同数值再次组合只会得到完全相同的三元组。

此外,因为数组已经排序,可以利用当前 nums[i] 对应的最小三数和与最大三数和进行剪枝。如果最小和已经大于 target,后续 nums[i] 更大,可以直接结束;如果最大和仍小于 target,则当前 nums[i] 不可能产生答案,可以直接进入下一轮。

由于 i 按升序遍历,left 也按升序移动,因此最终结果天然满足三元组之间的字典序要求。整体时间复杂度为 O(n²),可以满足 n≤3000 的数据规模;结果数组之外主要使用常数级双指针空间。

六、Java算法源码

public class OdTest {

    /**
     * 找出所有满足:
     * 1. 三数之和等于 target
     * 2. 至少包含两个奇数
     * 3. 三元组不重复
     */
    public static List<List<Integer>> findTriples(int[] nums, long target) {
        List<List<Integer>> result = new ArrayList<>();

        // 排序后可以使用双指针,把三重枚举 O(n^3) 优化为 O(n^2)。
        // 同时,相同元素会相邻,便于直接跳过重复值,实现三元组去重。
        Arrays.sort(nums);

        int n = nums.length;

        for (int i = 0; i < n - 2; i++) {

            // 第一个元素去重:
            // 如果 nums[i] 和上一次固定的数字相同,则可能产生完全相同的三元组。
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            /*
             * 剪枝1:
             * 当前 nums[i] 能组成的最小三数和已经大于 target。
             * 因为后面的 nums[i] 只会更大,所以可以直接结束整个循环。
             */
            long minSum = (long) nums[i] + nums[i + 1] + nums[i + 2];
            if (minSum > target) {
                break;
            }

            /*
             * 剪枝2:
             * 当前 nums[i] 和最大的两个数相加仍然小于 target,
             * 说明固定当前 nums[i] 不可能找到答案,直接处理下一个 i。
             */
            long maxSum = (long) nums[i] + nums[n - 2] + nums[n - 1];
            if (maxSum < target) {
                continue;
            }

            int left = i + 1;
            int right = n - 1;

            while (left < right) {
                // 使用 long 计算,避免一般场景下三个 int 相加出现溢出。
                long sum = (long) nums[i] + nums[left] + nums[right];

                if (sum < target) {
                    // 当前和偏小,需要增大左边的数字。
                    left++;
                } else if (sum > target) {
                    // 当前和偏大,需要减小右边的数字。
                    right--;
                } else {

                    /*
                     * 三数之和已经满足 target,
                     * 接下来检查三个数字中是否至少有两个奇数。
                     *
                     * 注意:不能使用 x % 2 == 1 判断所有奇数,
                     * 因为 Java 中 -1 % 2 == -1。
                     * 使用 x % 2 != 0 可以同时判断正奇数和负奇数。
                     */
                    int oddCount = 0;

                    if (nums[i] % 2 != 0) {
                        oddCount++;
                    }

                    if (nums[left] % 2 != 0) {
                        oddCount++;
                    }

                    if (nums[right] % 2 != 0) {
                        oddCount++;
                    }

                    if (oddCount >= 2) {
                        result.add(Arrays.asList(
                                nums[i],
                                nums[left],
                                nums[right]
                        ));
                    }

                    /*
                     * 当前数值组合已经处理完毕。
                     *
                     * 无论它是否满足奇偶条件,相同的 left/right 数值再次出现时,
                     * 得到的仍然是完全相同的三元组,因此统一跳过重复值。
                     */
                    int leftValue = nums[left];
                    int rightValue = nums[right];

                    while (left < right && nums[left] == leftValue) {
                        left++;
                    }

                    while (left < right && nums[right] == rightValue) {
                        right--;
                    }
                }
            }
        }

        return result;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        if (!scanner.hasNextLine()) {
            return;
        }

        /*
         * 题目示例输入:
         * -1,0,1,2,-1,-4
         *
         * 同时兼容:
         * [-1,0,1,2,-1,-4]
         */
        String arrayLine = scanner.nextLine()
                .trim()
                .replace("[", "")
                .replace("]", "");

        if (!scanner.hasNextLine()) {
            return;
        }

        long target = Long.parseLong(scanner.nextLine().trim());

        String[] parts = arrayLine.split("\\s*,\\s*");
        int[] nums = new int[parts.length];

        for (int i = 0; i < parts.length; i++) {
            nums[i] = Integer.parseInt(parts[i].trim());
        }

        List<List<Integer>> result = findTriples(nums, target);

        /*
         * 排序 + 双指针的遍历顺序天然满足字典序:
         * 第一个元素递增;
         * 第一个元素相同时,第二个元素递增。
         */
        for (List<Integer> triple : result) {
            System.out.println(
                    triple.get(0) + "," +
                            triple.get(1) + "," +
                            triple.get(2)
            );
        }
    }
}

七、效果展示

1、输入

3,3,2,2,3,2,4
8

2、输出

2,3,3

3、说明

专门验证重复数字。数组中有多个 2 和 3,但 2,3,3 只能输出一次。
在这里插入图片描述


🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 新系统 200分)

🏆本专栏收录于《华为OD机试(JAVA)真题》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天优快云在线答疑。

在这里插入图片描述

华为OD机试 新系统 双机位C卷 真题题库目录|机考题库 + 算法考点详解 本文整理华为OD机试(机考) 新系统真题题库,提供高频考点精析与详细题目内容,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解 和 在线OJ做题练习。华为OD机试新系统真题题库。 阅读详情

相关推荐

2026华为OD机考新系统真题 + 双机位C卷 + 往年真题 - 题库目录分值说明 + 考点说明+在线OJ

2026年4月1日起,华为OD机试正式切换至新系统模式!采用力扣模式,无需自己写输入! 难度大幅度降低。正在备考华为OD机试的同学,优先刷新系统机试真题,可大幅提升通过率。 新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!

算法大师! 45万+

2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解

并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!采用力扣模式,无需自己写输入!正在备考华为OD机试的同学,优先刷。新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有。2026年4月1日起,华为OD机试正式切换至。,可大幅提升通过率。

算法大师! 2万+

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解

每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天优快云在线答疑。

学Java,找哪吒 7万+

2026最新华为OD新系统机试解析 + 最新真题题库 + 备考策略

2026最新华为OD新系统机试改动变化讲解,分享最新华为OD新系统机试备考策略以及最新华为OD新系统机试题库,华为OD新系统机试题库包含的所有算法题均有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,实现高效备考。

qq_45776114的博客 7857

华为od机试新系统真题-奇偶三数之和(C/C++/Py/Java/Js/Go)

华为OD机试 新系统真题【奇偶三数之和】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【奇偶三数之和】多语言题解。

qq_45776114的博客 786

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解(Python/JS/C/C++)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释发现新题目,随时更新。

学Java,找哪吒 5万+

2026最新华为OD机试新系统 机考真题题库 + 真题考点分类 + 备考策略

华为OD机试新系统最新机考重点考点详解以及详细备考策略详解。收录华为OD机试真题中所有题目全部提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及提供在线OJ模拟做题。

qq_45776114的博客 2012

7.1华为OD机试真题 新系统 - 奇偶三数之和 (Java/Py/C/C++/Js/Go)

7.1华为OD机试真题 新系统 - 奇偶三数之和 (Java/Py/C/C++/Js/Go)

算法大师! 443

华为OD机试真题——对称美学(2025B卷:100分)Java/python/JavaScript/C++最佳实现

华为OD机试真题——对称美学(2025B卷:100分)Java/python/JavaScript/C++最佳实现

专注分享技术、实用优质教程、资源 2065

2026最新华为OD机试新系统机考真题- 真题题库目录|全覆盖题库 + 逐点算法考点详解

2026年4月1日起,华为OD机试正式切换至新系统模式!采用力扣模式,无需自己写输入! 难度大幅度降低。正在备考华为OD机试的同学,优先刷新系统机试真题,可大幅提升通过率。 新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!

算法大师! 2441

华为OD机考 新系统真题 【区分奇偶的数组排序】

华为OD机试 新系统真题【区分奇偶的数组排序】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【区分奇偶的数组排序】多语言题解。

qq_45776114的博客 506

【华为OD】2024年机试C卷、D卷真题集:最新的真题集题库 C/C++/Java/python/JavaScript

2024年C卷真题题集题库,有2种分数的题目列表,分别是100分的列表、200分的列表 从2023年11月开始,华为OD题目切换到C卷,基本上大概率会使用半年左右,要在2024年5月之前把这些题目都好好练习一下,可以得到很好的收获,基本上都是出的原题,提前恭喜大家都上岸。目前通过大大提供的真题练习,已经有上百人成功上岸了,而且大大还是一个老师,通过大大指导进入华为OD的学生已经有上千人了。 2024年5月之前,碰到原题的概率是98%以上。

十年以上编程经验的干货分享 2765

【吃瓜教程】周志华西瓜书课后习题第一章答案

第一章 1.1表1.1中若只包含编号为1和4的两个样例,试给出相应的版本空间。 编号 色泽 根蒂 敲声 好瓜(标记) 1 青绿 蜷缩 浊响 是Y 4 乌黑 稍蜷 沉闷 否N 知识储备: 假设空间: 所有假设组成的空间 版本空间:与训练集一致的假设集合 从假设空间到版本空间算法大致如下: 1.删除与正例不一致的假设且删除与反例一致的假设 2.删除与正例不一致的假设 3.删除与反例一致的假设 具体选择哪种

MaxQuYY的博客 8368

华为OD机试真题——素数伴侣(2025B卷:100分)Java/python/JavaScript/C++最佳实现

华为OD机试真题——素数伴侣(2025B卷:100分)Java/python/JavaScript/C++最佳实现

专注分享技术、实用优质教程、资源 1149

折叠式共源共栅放大器设计/备忘

w折叠式共源共栅基本结构如图

Czy1377004611的博客 3万+

别再踩坑了!Win10下用阿狸狗V3.2.6安装Cadence SPB 17.4的保姆级避坑指南

本文提供了Win10系统下使用阿狸狗V3.2.6安装Cadence SPB 17.4的详细避坑指南,涵盖环境准备、安装失败清理、分步安装与问题诊断、授权配置及典型故障排除等内容,帮助用户顺利完成安装并避免常见错误。

weixin_32576389的博客 359

2026最新华为OD机试新系统卷 全覆盖真题题库 + 真题考点分类 + 完整备考策略详解

华为OD机试新系统最新机考全覆盖题库,提供华为OD真题重点题型分类以及详细备考策略详解。华为OD近期真题所有题目全部提供C语言、Java、C++、Python、Go、JavaScript多语言源码实现,并提供完整思路讲解,以及提供在线OJ模拟做题。助力高效提升准备华为OD新系统机试效率。

qq_45776114的博客 898

Qt5开发从入门到精通——第一篇概述

Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形用户界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。在Qt程序开发过程中,除可以通过手写代码实现软件开发功能外,还可以通过Qt的GUI界面设计器(QtDesigner)进行界面的绘制和布局。该工具提供了Qt的基本可绘制窗口部件,如QWidget、QLabel、QPushButton和QVBoxLayout等。•对象查看器•属性编辑器。.........

weixin_44759598的博客 9503

华为OD机试真题——高矮个子排队(2025B卷:100分)Java/python/JavaScript/C++最佳实现

华为OD机试真题——高矮个子排队(2025B卷:100分)Java/python/JavaScript/C++最佳实现

专注分享技术、实用优质教程、资源 3979

告别IMEI!手把手教你用UUID实现Android设备唯一标识(兼容Android 10-13)

本文详细探讨了在Android 10及以上版本中,如何构建合规且高可用的设备唯一标识方案以替代被限制访问的IMEI。文章深入分析了Android设备标识符的演变,并提供了基于UUID/GUID的完整实现策略,包括生成算法、多级持久化存储方案(如MediaStore)、权限处理以及版本兼容性实践,帮助开发者应对Android 10-13的隐私政策变化。

weixin_28339967的博客 570

如何下载era5数据?(两种方式)

供水利大数据云计算课程同学参考使用#

Camiel_sweet的博客 1万+
上一篇: 华为OD机试 - 二叉树两节点间的最小跳数 - 二叉树(Python/JS/C/C++ 新系统 100分)
下一篇: 华为OD机试 - 奇偶三数之和(Python/JS/C/C++ 新系统 100分)
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2933原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值