HWOD Java机试回顾

本文解析了三道编程挑战题:寻找满足特定数学关系的数组元素、计算安装在航天器上的太阳能板最大面积、以及在树形目录结构中删除指定目录后的剩余目录ID。通过实例展示了算法实现过程。

hwod的机试,三道编程题,难度由易到简,考试时间150分钟,虽然迷迷糊糊但还是AC了,总的来说难度中上吧,我对自己代码的评价是容易理解但可能时间复杂度比较高(但也在题目允许的范围),总的来说可能有点暴力hh,凑合看。

1.A= B + 2C 是否有满足规则的数字组合

题目描述
给定一个正整数数组,检查数组中是否存在满足规则的数字组合
规则: A = B + 2C

输入描述
第一行输出数组的元素个数。
接下来一行输出所有数组元素,用空格隔开。

输出描述
如果存在满足要求的数,在同一行里依次输出规则里A/B/C的取值,用空格隔开。
如果不存在,输出0。

备注
数组长度在3-100之间。
数组成员为0-65535,数组成员可以重复,但每个成员只能在结果算式中使用一次。
如:数组成员为[0, 0, 1, 5],0出现2次是允许的,但结果0 = 0 + 2 * 0是不允许的,因为算式中使用了3个0。
用例保证每组数字里最多只有一组符合要求的解。

示例

输入:
4
2 7 3 0
输出:
7 3 2
说明
7 = 3 + 2 * 2
输入:
3
1 1 1
输出:
0
说明:
找不到满足条件的组合

代码

package cn.myProject;

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

public class Main {
    public static void main(String[] args) {
        //数据录入
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Integer[] arr = new Integer[n];
        for(int i = 0; i < n; i++){
            arr[i] = in.nextInt();
        }

        //对数组逆序排序
        Arrays.sort(arr, (o1, o2) -> o2 - o1);

        //思考题目逻辑A=B+2C -> C=(A-B)/2
        //还可得出:A > B和C;A-B是偶数
        int a = 0, b = 0, c = 0;    //初始化A, B, C
        boolean flag = false;   //是否找到了对应数据
        //粗暴遍历,别想太多,由头到尾,由大到小
        for(int i = 0; i < arr.length; i++){
            a = arr[i];
            //A > B且数组逆序,所以初始值为当前i+1即可,也是从头到尾粗暴遍历
            for(int j = i+1; j < arr.length; j++){
                b = arr[j];
                //需要A-B是偶数,C才能为继续求得
                if((a+b)%2 == 0){
                    c = (a - b)/2;
                    int kc = isExist(c, arr);   //查询数组中是否有对应C值,并返回目标C值的下标
                    //要求有C值,且下标与A和B的不重合
                    if(kc > 0 && kc != i && kc != j){
                        //满足条件后设置为true,跳出里循环即可
                        flag = true;
                        break;
                    }
                }
            }
            if(flag){
                //找到后跳出外循环
                break;
            }
        }
        if(!flag){
            System.out.println(0);
        }else{
            System.out.println(a + " " + b + " " + c);
        }
    }

    /**
     *
     * @param c
     * @param arr
     * @return
     */
    private static int isExist(int c, Integer[] arr) {
        //此方法的作用是检验c是否在数组中
        for(int i = 0; i < arr.length; i++){
            if(arr[i] == c){
                return i;
            }
        }
        return -1;
    }
}

废话:很简单捏

2.太阳能板最大面积

题目描述
给航天器一侧加装长方形和正方形的太阳能板(图中的斜线区域)
需要先安装两个支柱(图中的黑色竖条)
再在支柱的中间部分固定太阳能板
但航天器不同位置的支柱长度不同
太阳能板的安装面积受限于最短一侧的那支支柱的长度

现提供一组整型数组的支柱高度数据
假设每个支柱间的距离相等为一个单位长度
计算如何选择两根支柱可以使太阳能板的面积最大

输入描述
10,9,8,7,6,5,4,3,2,1
注释,支柱至少有两根,最多10000根,能支持的高度范围1~10^9的整数

柱子的高度是无序的
例子中的递减是巧合

输出描述
可以支持的最大太阳板面积:(10m高支柱和5m高支柱之间)
25

示例

输入
10,9,8,7,6,5,4,3,2,1
输出
25

备注
10米高支柱和5米高支柱之间宽度为5,高度取小的支柱高度也是5
面积为25
任取其他两根支柱所能获得的面积都小于25 所以最大面积为25。

代码

package cn.myProject;

import java.util.Scanner;

public class Main02 {
    public static void main(String[] args) {
        //数据录入和包装
        //注意:题目高度范围再加上可能到达的根数,我们的面积最好用long,粗暴一点的话,全用long包装就好了
        Scanner in = new Scanner(System.in);
        String[] arrStr = in.nextLine().split(",");
        long[] arr = new long[arrStr.length];
        for(int i = 0; i < arrStr.length; i++){
            arr[i] = Long.parseLong(arrStr[i]);
        }

        //算法本体
        long areaMax = 0;   //当前面积最大值
        long area;  //当前迭代的面积
        //粗暴遍历
        for(int i = 0; i < arr.length; i++){
            for(int j = 0; j < arr.length; j++){
                area = Math.min(arr[i], arr[j]) * (j-i);
                if(area > areaMax){
                    areaMax = area;
                }
            }
        }
        System.out.println(areaMax);
    }
}

废话:简单的要死了

3.删除文件系统目录

某文件系统中有N个目录,每个目录都一个独一无二的ID。每个目录只有一个父目录,但每个父目录下可以有零个或者多个子目录,目录结构呈树状结构。

假设,根目录的ID为0,且根目录没有父目录,其他所有目录的ID用唯一的正整数表示,并统一编号。
现给定目录ID和其父目录ID的对应父子关系表[子目录ID,父目录ID],以及一个待删除的目录ID,请计算并返回一个ID序列,表示因为删除指定目录后剩下的所有目录,返回的ID序列以递增序输出。

注意
1、被删除的目录或文件编号一定在输入的ID序列中;
2、当一个目录删除时,它所有的子目录都会被删除。

输入描述
输入的第一行为父子关系表的长度m;接下来的m行为m个父子关系对;最后一行为待删除的ID。序列中的元素以空格分割,参见样例。

输出描述
输出一个序列,表示因为删除指定目录后,剩余的目录ID。

示例

输入
5
8 6
10 8
6 0
20 8
2 6
8
输出
2 6

题目解析(别人的思路,好像更好一点,我的也不赖啦!)
这个题目是一个树类型的题,但是不是二叉树,所有涉及结构时,需要用一个list保持孩子节点。题目中说明每个目录的id唯一。
TreeMap<Integer, List>保存树结构,key是目录的唯一ID,value是孩子节点的Id的列表。之所以用TreeMap,是因为根据key的从小到大进行排序。后续的输出删除后的目录ID时,就不用再进行排序了
root保存根目录的ID
1、首先构建树保存到上述的TreeMap<Integer, List>
2、根据传入的ID进行树节点的删除,遍历孩子接口进行删除,先删除孩子节点,再删除当前节点。

代码

import java.util.*;

public class Main {
    //保存我们要删除的id
    static List<Integer> list = new LinkedList<>();

    public static void main(String[] args) {
        //数据录入和包装
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < n; i++){
            int key = scanner.nextInt();
            int value = scanner.nextInt();
            map.put(key, value);
        }
        int deleteKey = scanner.nextInt();

        //首先要存到list的就是题目给的id
        list.add(deleteKey);

        //算法:此部分作用用以保存要删除的id到list
        //以此遍历list中的id值,去查找map中value值为当前id的key,再将key加入到list中
        int searchI = 0;    //list中目前我们需要查找其子节点的id的下标
        Set<Integer> keySet = map.keySet();
        while(searchI < list.size()){   //结束条件是遍历完所有id
            for (Integer key : keySet){ //对每个key遍历
                //当map中value == list中下标为searchI的值时,添加到list
                //即:将searchI对应id文件的子文件id添加进去
                if(list.get(searchI) - map.get(key) == 0){//有减号的话就自动拆箱了
                    list.add(key);
                }
            }
            searchI++;  //遍历完成则操作list的下一个id
        }

        //算法:没什么算法,就是用来保存未被删除的元素到finalList并排序
        List<Integer> finalList = new ArrayList<>();
        for(Integer key : keySet){
            //若该key不在list中,则说明没被删除
            if(!list.contains(key)){
                finalList.add(key);
            }
        }
        Collections.sort(finalList);
        
        //输出结果
        for(int i = 0; i < finalList.size(); i++){
            if(i != finalList.size()-1){
                System.out.print(finalList.get(i) + " ");
            }else {
                System.out.print(finalList.get(i));
            }
        }

    }
}

废话:想了一阵子,还好

<think>嗯,用户想收集和整理华为OD考的题,归纳不同版本的题目内容。首先,我需要明确用户的具体需求是什么。可能用户正在准备参加华为OD的考,或者想帮助他人整理资料。不管怎样,整理题需要有系统的方法,否则容易混乱。 首先,用户提到的“题整理方法”和“归纳技巧”是关键。我得考虑如何高效地收集题。可能来源包括网络论坛、社交媒体群组、备考平台,或者官方发布的样题。例如,参考引用中提到的华为OD作弊、难度等问题,说明用户可能担心资料的准确性和完整性,所以需要验证题的真实性。 然后是分类方法。题目可能分为算法数据结构、编程题等。比如快速排序、动态规划这些算法题常见,字符串处理、数组操作也是高频考点。用户需要按题型、难度或知识点来分类,这样复习起来更有针对性。 接下来是版本差异。不同时间段的题可能有变化,比如2023年新增了某些题型,或者调整了难度。需要对比不同年份的题目,找出趋势,比如是否增加了对特定算法的考察频率。 在归纳技巧方面,建立结构化数据库可能有用,用Excel或Notion管理题目信息。同时,分析高频考点,比如二叉树遍历、链表操作等,帮助用户重点复习。还要注意题目变体,同一题目的不同描述或输入输出变化,这能帮助用户适应题目的灵活性。 用户可能遇到的挑战包括资料分散、真伪难辨,以及版本更新带来的变化。所以需要建议用户多渠道收集,交叉验证,并且定期更新资料库。此外,模拟考环境,练习手撕代码,也是备考的重要部分。 最后,用户可能还想知道如何利用这些整理好的资料进行有效复习,比如制定学习计划,针对性练习高频题目,或者参加模拟考。这些都是整理题后的下一步行动,用户可能需要进一步的指导,但当前问题主要集中在整理方法上,所以回答应集中在如何系统化整理和归纳。</think>### 华为OD题整理方法与归纳技巧 #### 一、题整理方法 1. **多渠道收集** - **官方渠道**:关注华为招聘官网、官方开发者社区发布的样题或考大纲[^1] - **技术论坛**:如牛客网、LeetCode讨论区,筛选用户分享的真题回忆录 - **社群资源**:加入备考群组(QQ/微信),整理群成员提供的题目片段 - **模拟平台**:使用第三方考模拟平台(如CodeTop)获取结构化题目 2. **分类标注** - **题型分类**:算法题(动态规划、贪心算法)、数据结构题(链表、二叉树)、数学题(概率计算) - **难度分级**:按华为OD定义的★~★★★等级划分,例如: $$T(n) = O(n \log n) \quad \text{// 快速排序类题目通常为★★级}$$ - **版本标识**:通过时间戳(如2023Q3)或地域标识(如南京研究所版)区分 3. **真实性验证** - **交叉比对**:至少3个独立来源确认同一题目 - **代码验证**:对编程题编写测用例,例如: ```python # 两数之和验证用例 assert two_sum([2,7,11,15], 9) == [0,1] ``` #### 二、归纳技巧 1. **结构化数据库** | 字段 | 说明 | 示例 | |------|------|------| | 题目ID | 唯一标识符 | HWOD2023-A01 | | 题干摘要 | 关键描述 | "二叉树层序遍历" | | 核心考点 | 知识点标签 | BFS/队列 | | 变体关联 | 相似题目链接 | HWOD2022-B05 | 2. **高频考点分析** - **Top 5算法**:快速排序、二分查找、DFS/BFS、滑动窗口、回溯法 - **数据结构热点**:链表翻转($O(1)$空间复杂度实现)、堆的应用、图的最短路径 - **数学相关**:排列组合计算(例如卡特兰数应用场景) 3. **版本差异处理** - **时间线对比**:制作版本演化矩阵 | 年度 | 新增题型 | 淘汰题型 | |------|----------|----------| | 2022 | 多线程同步问题 | 纯数学证明题 | | 2023 | 器学习基础题 | 简单数组遍历 | - **地域差异**:某些研究所侧重操作系统题(如内存管理),其他偏向网络编程 #### 三、实践建议 1. **建立自动化流程** - 使用Python爬虫定期抓取论坛新帖(需遵守平台规则) - 用自然语言处理(NLP)提取题目关键特征 ```python # 示例:题干关键词提取 from sklearn.feature_extraction.text import TfidfVectorizer corpus = ["二叉树中序遍历实现","动态规划求最长子序列"] vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(corpus) ``` 2. **变体题目关联** - **同源题目组**:将本质相同但表述不同的题目聚类,例如: - "数组中的第K大元素"(快速选择算法) - "前K个高频元素"(堆+哈希表) 3. **考环境模拟** - 限制IDE自动补全功能 - 严格遵循输入输出格式: ```text // 输入样例 3 1 2 3 // 输出要求 6 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值