华为机试题-数组去重和排序-Java

1 题目描述

给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。

2 输入描述

一个数组,之间用英文逗号(,)分割

3 输出描述

数组,按英文逗号(,)分割

4 示例

输入:1,3,3,3,5,5,5,4,2,2
输出:3,5,2,1,4
解释:
3 和 5 的出现次数为3,且3在5之前出现,所以3在5前面。
2的出现次数为2次。
1和4的出现次数为1次,且1在4前面。
即根据题意,输出3,5,2,1,4

5 代码解题

思路:记录数字的出现次数和首次出现的位置,先根据次数从大到小排序,如果次数相同,则根据首次出现位置从小到大排序

5.1 解法一

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        scanner.close();
        // 不存在数字比较,没有必要转int
        String[] ints = line.split(",")
        String result = sortCount(ints);
        System.out.println(result);
    }

    public static String sortCount(String[] arr) {
        final int initialCapacity = arr.length / 2;
        // 设置一个Map,记录数字的出现次数
        Map<String, Integer> countMap = new HashMap<>(initialCapacity);
        // 设置另一个Map,记录数字的首次出现的位置
        Map<String, Integer> indexMap = new HashMap<>(initialCapacity);
        // 遍历,并记录次数和位置
        for (int i = 0; i < arr.length; i++) {
            String key = arr[i];
            int count = countMap.getOrDefault(key, 0) + 1;
            countMap.put(key, count);
            if (!indexMap.containsKey(key)) {
                indexMap.put(key, i);
            }
        }
        // 排序
        return countMap.entrySet().stream().sorted((v1, v2) -> {
                if (!Objects.equals(v1.getValue(), v2.getValue())) {
                    // 从大到小输出
                    return v2.getValue() - v1.getValue();
                }
                // 从小到大输出
                return indexMap.get(v1.getKey()) - indexMap.get(v2.getKey());
            }).map(it -> it.getKey())
            .collect(Collectors.joining(","));
    }
}

解法二

利用额外的类来保存数值、出现次数、首次出现位置,比解法一更好理解,且高效

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        scanner.close();
        String[] ints = line.split(",");
        Map<String, Node> map = new HashMap<>();
        for (int i = 0; i < ints.length; i++) {
            String key = ints[i];
            if (map.containsKey(key)) {
                map.get(key).addCount();
            } else {
                map.put(key, new Node(key, i, 1));
            }
        }
        String result = map.values()
            .stream()
            .sorted(Node::compareTo)
            .map(it -> it.val)
            .collect(Collectors.joining(","));
        System.out.println(result);
    }

    // 写算法,就不要管什么开闭原则了
    public static class Node implements Comparable<Node> {
        String val;
        Integer index;
        Integer count;

        public Node(String val, Integer index, Integer count) {
            this.val = val;
            this.index = index;
            this.count = count;
        }

        public void addCount(){
            this.count++;
        }

        @Override
        public int compareTo(Node o) {
            if (Objects.equals(o.count, this.count)) {
                // 从小到大
                return this.index - o.index;
            }
            // 从大到小
            return o.count - this.count;
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
题目描述: 给定一个非负整数数组nums,按照题目要求,将nums中的元素拼接成一个最小的数,并输出该最小数的字符串形式。 例如,给定数组nums = [10,2],最小的数是102,则输出"102"。 解题思路: 要构成最小的数,首先需要将数组中的元素按照一定的规则进行排序排序的规则是将两个元素进行拼接后,比较大小。 具体步骤如下: 1. 将数组转化为字符串数组,方便拼接和比较。 2. 对字符串数组进行排序排序规则是如果拼接后的字符串a+b小于b+a,则a排在b前面。 3. 将排序后的字符串数组按顺序拼接起来,形成最小的数。 具体实现如下: 首先,将数组nums转换为字符串数组strs。 然后,使用排序算法对字符串数组strs进行排序排序规则是使用自定义的函数compare,实现拼接后的字符串的大小比较。 最后,将排序后的字符串数组strs按顺序拼接起来,形成最小的数min_num。 返回min_num。 时间复杂度分析: 对于给定的n个元素的数组,首先需要将数组转换成字符串数组,时间复杂度为O(n)。 然后,使用排序算法对字符串数组进行排序,其时间复杂度为O(nlogn)。 最后,将排序后的字符串数组按顺序拼接起来,时间复杂度为O(n)。 所以,总的时间复杂度为O(nlogn)。 空间复杂度分析: 除了题目给定的数组外,需要额外的空间来存储转换后的字符串数组,其空间复杂度为O(n)。 综上所述,解决该题的算法的时间复杂度为O(nlogn),空间复杂度为O(n)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值