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;
}
}
}