华为OD机试真题 Java 实现【求最大数字】【2023 Q1 200分】,附详细解题思路

在这里插入图片描述

目录

    • 专栏导读
    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
    • 四、解题思路
    • 五、Java算法源码
    • 六、效果展示
      • 1、输入
      • 2、输出
      • 3、思路
      • 4、再输入
      • 5、再输出

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。

  • 专栏福利:限时订阅49.9,订阅后可加入华为OD刷题群,获得哪吒优先答疑机会(华为OD刷题指导,远程代码调试),群里大佬众多可以抱团取暖,群友刷题经验分享,考试经验分享。

在这里插入图片描述

一、题目描述

给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除,删除某个重复的数字后,其它数字相对位置保持不变。

如"34533",数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值"4533",请返回经过删除操作后的最大的数值,以字符串表示。

二、输入描述

第一行为一个纯数字组成的字符串,长度范围:[1,100000]。

三、输出描述

输出经过删除操作后的最大的数值。

四、解题思路

  1. 输入一个数字;
  2. 定义一个map,存储每个数字出现的次数;
  3. 遍历输入的数字;
  4. 获取每个数字出现的次数,没出现,默认为0;
  5. 如果出现的次数小于2,则添加到map和builder中;
  6. 如果出现的次数大于2,遍历最终返回的数字builder;
    1. 以78877为例,当遍历到“第三个7”的时候;
    2. 如果“某个7”比它后面的那个数小,表示,删除“某个7”的话,数会变大;
    3. 故将“某个7”删除,并将“第三个7”添加到最终返回的数字builder中即可
  7. 输出最终返回的数字;

复杂度分析:

时间复杂度:排序的时间复杂度为O(nlogn),其中n是数组的长度。字符串拼接的时间复杂度为O(n)。因此,总体时间复杂度为O(nlogn)
空间复杂度:使用了额外的字符串数组存储转换后的字符串,空间复杂度为O(n)。另外,使用了StringBuilder来拼接字符串,空间复杂度也为O(n)。因此,总体空间复杂度为O(n)

五、Java算法源码

public static void main(String[] args) {
   Scanner sc = new Scanner(System.in);
    String input = sc.nextLine();
    // 存储每个数字出现的次数
    Map<Character, Integer> map = new HashMap<Character, Integer>();
    // 最终返回的数字
    StringBuilder builder = new StringBuilder();
    // 遍历输入的数字
    for (Character c : input.toCharArray()) {
        // 获取每个数字出现的次数,没出现,默认为0
        Integer count = map.getOrDefault(c, 0);
        // 如果出现的次数小于2,则添加到map和builder中
        if (count < 2) {
            map.put(c, count + 1);
            builder.append(c);
        } else {// 如果出现的次数大于2
            // 遍历最终返回的数字builder
            for (int i = 0; i < builder.toString().length() - 1; ++i) {
                // 当前数字
                char currCh = builder.charAt(i);
                // 下一个数字
                char nextCh = builder.charAt(i + 1);
                // 以78877为例,当遍历到“第三个7”的时候
                // 遍历builder,获取前几个7的位置
                // 如果“某个7”比它后面的那个数小,表示,删除“某个7”的话,数会变大
                // 故将“某个7”删除,并将“第三个7”添加到最终返回的数字builder中即可
                if (currCh == c && currCh < nextCh) {
                    builder.deleteCharAt(i);
                    builder.append(c);
                    break;
                }
            }
        }
    }
    System.out.println(builder);
}

六、效果展示

1、输入

78877

2、输出

8877

3、思路

  1. 当遍历到“第三个7”的时候;
  2. 如果“某个7”比它后面的那个数小,表示,删除“某个7”的话,数会变大;
  3. 故将“某个7”删除,并将“第三个7”添加到最终返回的数字中即可;

4、再输入

如果我输入的多一点呢?

7667756545

5、再输出

  1. 理性分析一下哈;
  2. 7出现了三次,故删除一个,第一个7后面的是6,故不可删除;
  3. 删除第二个7和第三个7效果一样,第三个7后面的是5,故不可删除;
  4. 但是由于删除第三个7,带来的效果最小,变为766756545
  5. 6也出现了三次,故删除一个,第二个6后面是7,故删除一个,数会变大,变为76756545
  6. 5也出现了三次,第一个5后面的是6,故删除第一个5,变为7676545

你觉得对吗,自己测试一下吧

华为OD机试真题 Java 实现【求最大数字】【2023 Q1 200分】,附详细解题思路_第1张图片


下一篇:华为OD机试真题 Java 实现【跳房子II】【2023 B卷 100分】,附详细解题思路

本文收录于,华为OD机试(JAVA)(2022&2023)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

你可能感兴趣的:(搬砖工逆袭Java架构师,华为od,java,华为,程序人生,学习)