【编程题目 | 100分】数组去重和排序 [ 100 / 中等 ]
数组去重和排序
题目描述:
给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。
输入描述:
一个数组
输出描述:
去重排序后的数组
示例 1:
输入
1,3,3,3,2,4,4,4,5
输出
3,4,1,2,5
备注
数组大小不超过100 数组元素值大小不超过100
思路分析
又一个哈希表的排序,这个排序相对简单,只需要对value降序排,key读入的顺序,就是第一次出现索引的先后顺序。
HashMap的排序,需要先把HashMap转为list,再对list进行排序。
List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
// 直接使用lambda表达式排序
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
多关键字排序的话:
Map<Integer, int[]> map = new HashMap<>();
// Map按value排序,先将map转为list,再排序list(按value值进行排序)
List<Map.Entry<Integer, int[]>> list = new ArrayList<Map.Entry<Integer, int[]>>(map.entrySet());
// 通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<Integer, int[]>>() {
@Override
public int compare(Map.Entry<Integer, int[]> o1, Map.Entry<Integer, int[]> o2) {
// 降序排序
int re = o1.getValue()[0] - o2.getValue()[0];
if (re != 0) {
return re;
}
re = o1.getValue()[1] - o2.getValue()[1];
if (re != 0) {
return re;
}
return 0;
}
});
// 直接使用lambda表达式排序
list.sort((o1, o2) -> (o1.getValue()[0]==o2.getValue()[0]?(o1.getValue()[1]-o2.getValue()[1]):(o1.getValue()[0]-o2.getValue()[0])));
具体请参考:华为机试:身高体重排序
参考代码:
import java.util.*;
public class arraySetSort {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] str = in.nextLine().split(",");
int[] ints = new int[str.length];
for (int i = 0; i < ints.length; i++) {
ints[i] = Integer.parseInt(str[i]);
}
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < ints.length; i++) { // 统计数字出现的频次
map.put(ints[i], map.getOrDefault(ints[i], 0) + 1);
}
// Map按value排序,先将map转为list,再排序list
List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
for (int i = 0; i < list.size(); i++) {
Map.Entry<Integer, Integer> entry = list.get(i);
if (i != list.size() - 1) {
System.out.print(entry.getKey() + ",");
} else {
System.out.println(entry.getKey());
}
}
}
}
非常感谢同学提出的意见,特此进行修改。
由于HashMap无序,无法表示字符原先的顺序,因此这里修改为使用LinkedHashMap
。其中,LinkedHashMap继承自HashMap,它的多种操作都是建立在HashMap操作的基础上的。同HashMap不同的是,LinkedHashMap维护了一个Entry的双向链表,保证了插入的Entry中的顺序。这也是Linked的含义。
修改:
import java.util.*;
public class arraySetSort {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] str = in.nextLine().split(",");
int[] ints = new int[str.length];
for (int i = 0; i < ints.length; i++) {
ints[i] = Integer.parseInt(str[i]);
}
// HashMap<Integer, Integer> map = new HashMap<>();
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < ints.length; i++) { // 统计数字出现的频次
map.put(ints[i], map.getOrDefault(ints[i], 0) + 1);
}
// Map按value排序,先将map转为list,再排序list
// List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
LinkedList<Map.Entry<Integer,Integer>> list = new LinkedList<>(map.entrySet());
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
for (int i = 0; i < list.size(); i++) {
Map.Entry<Integer, Integer> entry = list.get(i);
if (i != list.size() - 1) {
System.out.print(entry.getKey() + ",");
} else {
System.out.println(entry.getKey());
}
}
}
}