[英]An optimized way to completely remove elements from a list that occur more than n times
解决方案.java
public class Solution {
public static ArrayList<Integer> solution(int[] data, int n){
ArrayList<Integer> list = new ArrayList<>();
if(n == 0){
list.add(0);
return list;
}
for (int x : data) {
int sameTaskCount = 0;
for (int y : data) {
if (y == x)
sameTaskCount++;
}
if (sameTaskCount <= n)
list.add(x);
}
return list;
}
public static void main (String[] args) {
int[] list = {1, 2, 2, 3, 3, 3, 4, 5, 5};
int n = 1;
ArrayList<Integer> newList = solution(list, n);
System.out.println(newList);
}}
解决方案.java(使用 HashMap) HASMAP 不保留顺序,因此被刮掉
public class Solution1 {
public static ArrayList<Integer> solution(int[] data, int n){
HashMap<Integer, Integer> elementCountMap = new HashMap<>();
for (int i : data) {
if(elementCountMap.containsKey(i))
elementCountMap.put(i, elementCountMap.get(i)+1);
else
elementCountMap.put(i, 1);
}
elementCountMap.entrySet().removeIf(entry ->(entry.getValue() > n));
return new ArrayList<>(elementCountMap.keySet());
}
public static void main (String[] args) {
int[] list = {1, 2, 2, 3, 3, 3, 4, 5, 5};
int n = 1;
ArrayList<Integer> newList = solution(list, n);
System.out.println(newList);
}}
是否有另一种方法可以减少执行时间? 我在这里使用的示例输入只是为了测试目的,输入最多可以是 99 个整数,并且输入不会总是被排序。 这两个程序都在 IDE 中运行良好,但是当我提交代码时它们都失败了多个测试用例。
这是实际的问题陈述:
编写一个名为
solution(data, n)
的 function ,它接收一个少于 100 个整数和一个数字n
的列表,并返回相同的列表,但所有出现超过n
次的数字都被完全删除。 返回的列表应保持与原始列表相同的顺序。 例如,如果 data 是 [5, 10, 15, 10, 7] 并且 n 是 1,则 solution(data, n) 将返回列表 [5, 15, 7] 因为 10 出现两次,因此从完整列出。约束:Java 8,执行时间有限,无通配符导入
正如已经说过的,最好为输入数组/列表计算频率 map 并过滤掉超过给定阈值的元素:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Solution {
// solution for array
public static List<Integer> solution(int[] arr, int n) {
if (n < 1) {
return Collections.emptyList();
}
Supplier<Stream<Integer>> streamSupplier = () -> Arrays.stream(arr).boxed();
Map<Integer, Integer> freqMap = streamSupplier.get()
.collect(Collectors.groupingBy(x -> x, Collectors.summingInt(x -> 1)));
return streamSupplier.get().filter(x -> freqMap.get(x) <= n).collect(Collectors.toList());
}
// solution for ArrayList
public static List<Integer> solution(ArrayList<Integer> list, int n) {
if (n < 1) {
return Collections.emptyList();
}
Map<Integer, Integer> freqMap = list.stream()
.collect(Collectors.groupingBy(x -> x, Collectors.summingInt(x -> 1)));
list.removeIf(x -> freqMap.get(x) > n);
return list;
}
}
这个想法是创建数组中数字的频率 map ,然后过滤频率小于n
的数字。 Stream
API 以简洁明了的方式更容易完成。
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Main {
public static List<Integer> solution(int[] data, int n) {
return Arrays.stream(data)
.boxed()
.collect(Collectors.groupingBy(Function.identity())).values()
.parallelStream()
.filter(list -> list.size() <= n)
.flatMap(List::stream)
.collect(Collectors.toList());
}
public static void main(String[] args) {
int[] list = { 1, 2, 2, 3, 3, 3, 4, 5, 5 };
// Test
int n = 2;
System.out.println(solution(list, n));
}
}
Output:
[1, 2, 2, 4, 5, 5]
Oracle关于Stream
API的教程:
与我之前的尝试相比,这似乎相对较快。 它是使分组过程短路的混合解决方案。 它使用 map 但仅供内部使用,因此它保留剩余元素的顺序并使用 Java 1.8 或更早版本。
public static List<Integer> solution(int[] data, int n) {
Map<Integer, List<Integer>> map = new HashMap<>();
List<Integer> list = new LinkedList<>();
Set<Integer> set = new HashSet<>();
for (int i : data) {
if (set.contains(i)) {
continue; // already removed
}
list.add(i);
map.computeIfAbsent(i, k->new ArrayList<>()).add(i);
List<Integer> temp = map.get(i);
if (temp.size() > n) {
set.add(i);
list.removeAll(temp);
}
}
return list;
}
public static void main(String[] args) {
Random r = new Random(23);
int[] data = r.ints(20, 1, 6).toArray();
System.out.println(Arrays.toString(data));
int n = 4;
List<Integer> newList = solution(data,n);
System.out.println(newList);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.