华为od机试题3 真题

以下题目附带Java解法,是我个人写的,不一定是标准答案,没有真正的测试数据,只能说是我自己认为通过率100%,也不一定是最优解。如果有错误或是有更好的解法,请评论告诉我!!!

67.最小字符串

  题目描述:
  给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。
  变换规则:交换字符串中任意两个不同位置的字符。
  输入描述:
  一串小写字母组成的字符串s。
  输出描述:
  按照要求进行变换得到的最小字符串。
  备注:
  s是都是小写字符组成
  1<=s.length<=1000
  示例
  输入:abcdef
  输出:abcdef
  说明:abcdef已经是最小字符串,不需要交换
 
  输入:bcdefa
  输出:acdefb
  说明:a和b进行位置交换,可以得到最小字符串
    // 最小字符串
    // 解题思路:遍历每一个元素,找到最小的,与第一个元素交换,如果第一个元素是最小的,则找第二个元素与第二小的元素交换,以此类推
    public static void test067() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        char[] chars = line.toCharArray();
        // 遍历每一个元素
        for (int j = 0; j < chars.length; j++) {
            // 存放最小的元素
            char minValue = chars[j];
            // 存放最小元素的索引
            int minIndex = j;
            // 遍历往后的所有元素
            for (int i = j + 1; i < chars.length; i++) {
                // 使用<=是因为要拿到排在最后的最小元素
                if (chars[i] <= minValue) {
                    minValue = chars[i];
                    minIndex = i;
                }
            }
            // 当最小元素不是第一个时,则交换第一个元素与最小元素的位置,输出后结束
            if (minIndex != j && chars[j] != chars[minIndex]) {
                chars[minIndex] = chars[j];
                chars[j] = minValue;
                System.out.println(new String(chars));
                return;
            }
        }
        // 当元素是按顺序排的,则直接输出
        System.out.println(line);
    }

66.最长元音字符串

  定义当一个字符串只有元音字母(a,e,i,o,u,A,E,I,O,U)组成,
  称为元音字符串,现给定一个字符串,请找出其中最长的元音字符串,
  并返回其长度,如果找不到请返回0,
  字符串中任意一个连续字符组成的子序列称为该字符串的子串
  <p>
  输入描述:
  一个字符串其长度 0<length ,字符串仅由字符a-z或A-Z组成
  输出描述:
  一个整数,表示最长的元音字符子串的长度
  <p>
  示例1:
  输入
  asdbuiodevauufgh
  输出
  3
  说明:
  最长的元音字符子串为uio和auu长度都为3,因此输出3
    // 最长元音字符串
    // 解题思路:定义一个元音字符数组,判断字符是否在数组中,且是连续的,定义一个临时长度来记录连续且元音字符长度,保留最长的
    public static void test066() {
        Scanner sc = new Scanner(System.in);
        char[] chars = sc.nextLine().toCharArray();
        List<Character> list = new ArrayList<>();
        list.add('a');
        list.add('e');
        list.add('i');
        list.add('o');
        list.add('u');
        list.add('A');
        list.add('E');
        list.add('I');
        list.add('O');
        list.add('U');
        // 最大长度
        int maxLen = 0;
        // 临时长度
        int tempLen = 0;
        for (int i = 0; i < chars.length; i++) {
            // 元音且连续
            while (i < chars.length && list.contains(chars[i])) {
                i++;
                tempLen++;
            }
            // 保留最长串
            maxLen = Math.max(maxLen, tempLen);
            // 初始化
            tempLen = 0;
        }
        System.out.println(maxLen);
    }

65.字母所在字符串中的位置索引

  输入一个由N个大小写字母组成的字符串
  按照ASCII码值从小到大进行排序
  查找字符串中第K个最小ASCII码值的字母(k>=1)
  输出该字母所在字符串中的位置索引(字符串的第一个位置索引为0)
  k如果大于字符串长度则输出最大ASCII码值的字母所在字符串的位置索引
  如果有重复字母则输出字母的最小位置索引

  输入描述
  第一行输入一个由大小写字母组成的字符串
  第二行输入k k必须大于0 k可以大于输入字符串的长度

  输出描述
  输出字符串中第k个最小ASCII码值的字母所在字符串的位置索引
  k如果大于字符串长度则输出最大ASCII码值的字母所在字符串的位置索引
  如果第k个最小ASCII码值的字母存在重复  则输出该字母的最小位置索引

  示例一
  输入
  AbCdeFG
  3
  输出
  5
  说明
  根据ASCII码值排序,第三个ASCII码值的字母为F
  F在字符串中位置索引为5(0为字符串的第一个字母位置索引)
 
  示例二
  输入
  fAdDAkBbBq
  4
  输出
  6
  说明
  根据ASCII码值排序前4个字母为AABB由于B重复则只取B的第一个最小位置索引6
  而不是第二个B的位置索引8
    // 字母所在字符串中的位置索引
    // 解题思路:将字符串转为集合,对集合进行排序,找到指定位置的值,在字符串中找该字符所在位置索引
    public static void test065() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        char[] chars = line.toCharArray();
        int index = sc.nextInt();
        int length = chars.length;
        List<Character> list = new ArrayList<>();
        for (int i = 0; i < length; i++) {
            list.add(chars[i]);
        }
        // 对集合进行排序
        Collections.sort(list);
        // 大于字符长度
        if (index > length) {
            // 输出排序后最后一个字符所在字符串的索引位置
            System.out.println(line.indexOf(list.get(length - 1)));
        } else {
            // 输出指定位置字符所在字符串的索引位置
            System.out.println(line.indexOf(list.get(index - 1)));
        }
    }

64.计算图形面积

  绘图机器的绘图笔初始位置在原点(0,0)
  机器启动后按照以下规则来进行绘制直线
  1. 尝试沿着横线坐标正向绘制直线
  直到给定的终点E
  2. 期间可以通过指令在纵坐标轴方向进行偏移
  offsetY为正数表示正向偏移,为负数表示负向偏移
 
  给定的横坐标终点值E 以及若干条绘制指令
  请计算绘制的直线和横坐标轴以及x=E的直线组成的图形面积
  输入描述:
  首行为两个整数N 和 E
  表示有N条指令,机器运行的横坐标终点值E
  接下来N行 每行两个整数表示一条绘制指令x offsetY
  用例保证横坐标x以递增排序的方式出现
  且不会出现相同横坐标x
  取值范围:
  0<N<=10000
  0<=x<=E<=20000
  -10000<=offsetY<=10000
 
  输出描述:
  一个整数表示计算得到的面积 用例保证结果范围在0到4294967295之内
  示例1:
  输入:
  4 10
  1 1
  2 1
  3 1
  4 -2
  输出:
  12
 
  示例2:
  输入:
  2 4
  0 1
  2 -2
  输出:
  4

在这里插入图片描述

    // 这个通过率好像只有95%,没有具体的测试数据,我也不知道哪里有问题
    // 计算图形面积
    // 解题思路:每个点的面积等于下一个点x值 - 当前点x值 乘以 当前点y的累计值。最后一个点则是:终点x值 - 当前点x值 乘以 当前点y的累计值
    public static void test064() {
        Scanner sc = new Scanner(System.in);
        String line1 = sc.nextLine();
        String[] split1 = line1.split(" ");
        int num = Integer.parseInt(split1[0]);
        int end = Integer.parseInt(split1[1]);
        // 存放x坐标的值
        List<Integer> listX = new ArrayList<>();
        // 存放y坐标的值
        List<Integer> listY = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            String line = sc.nextLine();
            String[] split = line.split(" ");
            listX.add(Integer.parseInt(split[0]));
            listY.add(Integer.parseInt(split[1]));
        }
        // y的累计值
        int sumY = 0;
        // 总面积
        int sumArea = 0;
        for (int i = 0; i < num; i++) {
            // 最后一个点
            if (i == num - 1) {
                // y的累计值
                sumY += listY.get(i);
                // 终点x值 - 当前点x值 乘以 当前点y的累计值
                sumArea += (end - listX.get(i)) * Math.abs(sumY);
            } else {
                // y的累计值
                sumY += listY.get(i);
                // 下一个点x值 - 当前点x值 乘以 当前点y的累计值
                sumArea += (listX.get(i + 1) - listX.get(i)) * Math.abs(sumY);
            }
        }
        System.out.println(sumArea);
    }

63.剩余可用字符集

  给定两个字符集合
  一个是全量字符集
  一个是已占用字符集
  已占用字符集中的字符不能再使用
  要求输出剩余可用字符集
 
  输入描述
  1. 输入一个字符串 一定包含@
 
  @前为全量字符集 @后的为已占用字符集
  2. 已占用字符集中的字符
  一定是全量字符集中的字符
  字符集中的字符跟字符之间使用英文逗号隔开
  3. 每个字符都表示为字符+数字的形式
  用英文冒号分隔
  比如a:1标识一个a字符
  4. 字符只考虑英文字母,区分大小写
  数字只考虑正整型 不超过100
  5. 如果一个字符都没被占用 @标识仍存在
  例如 a:3,b:5,c:2@
  
  输出描述:
  输出可用字符集
  不同的输出字符集之间用回车换行
  注意 输出的字符顺序要跟输入的一致
  不能输出b:3,a:2,c:2
  如果某个字符已全部占用 则不需要再输出
  
  示例一:
  输入
  a:3,b:5,c:2@a:1,b:2
  输出
  a:2,b:3,c:2
  说明:
  全量字符集为三个a,5个b,2个c
  已占用字符集为1个a,2个b
  由于已占用字符不能再使用
  因此剩余可用字符为2个a,3个b,2个c
  因此输出a:2,b:3,c:2
    // 如果全量字符中有重复的,是相加还是取最后一个?? 我做的是相加,如果取最后一个则先remove,在put,就能保证插入顺序
    // 剩余可用字符集
    // 解题思路:使用按插入顺序排列的LinkedHashMap来存储全量字符集,在减掉已用字符集
    public static void test063() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] split = line.split("@");
        // 一个字符都没被占用
        if (line.charAt(line.length() - 1) == '@') {
            System.out.println(line.substring(0, line.length() - 1));
            return;
        }
        String[] allString = split[0].split(",");
        String[] userString = split[1].split(",");
        // LinkedHashMap 按插入顺序排列
        Map<String, Integer> map = new LinkedHashMap<>();
        // 遍历全量字符串,存进LinkedHashMap中
        for (int i = 0; i < allString.length; i++) {
            String[] strAndNum = allString[i].split(":");
            String str = strAndNum[0];
            int num = Integer.parseInt(strAndNum[1]);
            if (map.containsKey(str)) {
                map.put(str, map.get(str) + num);
            } else {
                map.put(str, num);
            }
        }
        // 遍历用过的字符串,在LinkedHashMap中减掉使用的次数
        for (int i = 0; i < userString.length; i++) {
            String[] strAndNum = userString[i].split(":");
            String str = strAndNum[0];
            int num = Integer.parseInt(strAndNum[1]);
            map.put(str, map.get(str) - num);
        }
        // 拼接输出的字符串
        StringBuilder sb = new StringBuilder();
        for (String s : map.keySet()) {
            // 只输出有剩余的字符串
            if (map.get(s) > 0) {
                sb.append(s + ":" + map.get(s) + ",");
            }
        }
        System.out.println(sb.substring(0, sb.length() - 1));
    }

62.字符串解压缩

 有一种简易压缩算法:针对全部为小写英文字母组成的字符串,
 将其中连续超过两个相同字母的部分压缩为连续个数加该字母
 其他部分保持原样不变.
 例如字符串aaabbccccd  经过压缩变成字符串 3abb4cd
 请您编写解压函数,根据输入的字符串,
 判断其是否为合法压缩过的字符串
 若输入合法则输出解压缩后的字符串
 否则输出字符串"!error"来报告错误

 输入描述
 输入一行,为一个ASCII字符串
 长度不超过100字符
 用例保证输出的字符串长度也不会超过100字符串

 输出描述
 若判断输入为合法的经过压缩后的字符串
 则输出压缩前的字符串
 若输入不合法 则输出字符串"!error"

 示例一:
 输入
 4dff
 输出
 ddddff
 说明
 4d扩展为4个d ,故解压后的字符串为ddddff

 示例二
 输入
 2dff
 输出
 !error
 说明
 2个d不需要压缩 故输入不合法

 示例三
 输入
 4d@A
 输出
 !error
 说明
 全部由小写英文字母做成的字符串,压缩后不会出现特殊字符@和大写字母A
 故输入不合法
    // 字符串解压缩
    // 解题思路:遍历每个字符,取出字符前的数字进行解压缩
    public static void test062(){
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        // 替换掉合法字符
        String replaceAll = line.replaceAll("[1-9]|[a-z]", "");
        // 替换掉合法字符后,长度不为0,则不合法 || 最后一个字符是数字,不合法
        if (replaceAll.length() > 0 || Character.isDigit(line.charAt(line.length() - 1))) {
            System.out.println("!error");
            return;
        }
        // 存放结果
        String resLine = line;
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            // 获取字符前的数字
            if (Character.isDigit(c)){
                int start = i;
                while (Character.isDigit(line.charAt(i+1))){
                    i++;
                }
                int num = Integer.parseInt(line.substring(start, i+1));
                // 2不需要压缩,不合法
                if (num <= 2) {
                    System.out.println("!error");
                    return;
                }
                // 解压缩
                resLine = resLine.replaceFirst(num+"", getString(num, line.charAt(i + 1)));
            }
        }
        System.out.println(resLine);
    }

61. 相等的连续子串

  给你两个字符串t和p
  要求从t中找到一个和p相同的连续子串
  并输出该子串第一个字符的下标
  输入描述
  输入文件包括两行 分别表示字符串t和p
  保证t的长度不小于p
  且t的长度不超过1000000
  p的长度不超过10000
  输出描述
  如果能从t中找到一个和p相等的连续子串,
  则输出该子串第一个字符在t中的下标
  下标从左到右依次为1,2,3,...;
  如果不能则输出 "No"
  如果含有多个这样的子串
  则输出第一个字符下标最小的
 
  示例一:
  输入:
  AVERDXIVYERDIAN
  RDXI
  输出
  4
    // 相等的连续子串
    // 解题思路:双层循环,遍历每个字符,依次判断是否与子串相同,当相同长度与子串相等时,结束并输出;否则进入下一个字符进行判断
    public static void test061() {
        Scanner sc = new Scanner(System.in);
        String t = sc.nextLine();
        String p = sc.nextLine();
        for (int i = 0; i < t.length(); i++) {
            // 开始字符位置
            int start = i;
            // 与子串相同字符个数
            int j = 0;
            // 与子串进行比对
            while (start < t.length() && j < p.length() && t.charAt(start) == p.charAt(j)) {
                // 索引位置向前
                start++;
                // 个数加1
                j++;
            }
            // 当子串相同字符个数 == 子串长度,满足条件,输入并结束
            if (j == p.length()) {
                System.out.println(i + 1);
                return;
            }
        }
        System.out.println("No");
    }

59.员工出勤奖

  公司用一个字符串来标识员工的出勤信息
  absent:    缺勤
  late:      迟到
  leaveearly:早退
  present:   正常上班
 
  现需根据员工出勤信息,判断本次是否能获得出勤奖,
  能获得出勤奖的条件如下:
  1.缺勤不超过1次
  2.没有连续的迟到/早退
  3.任意连续7次考勤 缺勤/迟到/早退 不超过3次
 
  输入描述:
  用户的考勤数据字符串记录条数  >=1
  输入字符串长度 <10000 ;
  不存在非法输入
  如:
  2
  present
  present absent present present leaveearly present absent
 
  输出描述:
  根据考勤数据字符串
  如果能得到考勤奖输出true否则输出false
  对于输出示例的结果应为
  true false
 
  示例一:
  输入:
  2
  present
  present present
  输出:
  true true
 
  示例二
  输入:
  2
  present
  present absent present present leaveearly present absent
  输出:
  true false
    // 员工出勤奖
    // 解题思路:将输入的内容放在集合中,遍历集合,按条件依次判断
    public static void test059() {
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
        List<String> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            String line = sc.nextLine();
            list.add(line);
        }
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            String[] split = str.split(" ");
            // 1.缺勤不超过1次
            int absentCount = 0;
            for (int j = 0; j < split.length; j++) {
                if ("absent".equals(split[j])) {
                    absentCount++;
                }
            }
            if (absentCount > 1) {
                System.out.print(false + " ");
                // 退出此次循环
                continue;
            }
            // 2.没有连续的迟到/早退
            if (str.contains("late leaveearly") || str.contains("leaveearly late") || str.contains("leaveearly leaveearly") || str.contains("late late")) {
                System.out.print(false + " ");
                // 退出此次循环
                continue;
            }
            // 3.任意连续7次考勤 缺勤/迟到/早退 不超过3次
            // 用于存放 缺勤/迟到/早退 最大次数
            int count = 0;
            // 用于存放 缺勤/迟到/早退 临时次数
            int noPresent = 0;
            if (split.length > 7) {
                for (int j = 0; j + 7 <= split.length; j++) {
                    for (int k = j; k < 7 + j; k++) {
                        if ("absent".equals(split[k]) || "late".equals(split[k]) || "leaveearly".equals(split[k])) {
                            noPresent++;
                        }
                    }
                    count = Math.max(count, noPresent);
                    noPresent = 0;
                }
            } else {
                for (int j = 0; j < split.length; j++) {
                    if ("absent".equals(split[j]) || "late".equals(split[j]) || "leaveearly".equals(split[j])) {
                        count++;
                    }
                }
            }
            if (count > 3) {
                System.out.print(false + " ");
                // 退出此次循环
                continue;
            }
            // 都符合,则输出true
            System.out.print(true + " ");
        }
    }

更多华为od机试题请点这里<华为od机试题4 真题>,每篇8题,有更多的题也请告诉我啊

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chenzm666666

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

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

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

打赏作者

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

抵扣说明:

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

余额充值