请看下面的cpp代码
string ans = "NO";
map<int,vi> idv ; //vi is vector of int
for(int i=1;i<=n;i++)
idv.[arr[i]].push_back(i);
//frequecy >= 3
for(auto el:idv){
if(el.ss.size() >= 3){
ans = "YES";}
}
//non adjecent equal elements
for(auto el:idv)
{
if(el.ss.size() == 2 && el.ss[0] != el.ss[1]-1)
{
ans = "YES";
}
}
cout<<ans<<endl;
我的java翻译代码
String ans = "NO";
Map<Integer,List<Integer>> map = new HashMap<>();
for (int i : arr) {
// map.merge(i,1,Integer::sum);
// map.put(i, )
List<Integer> temp = map.getOrDefault(i, new ArrayList<>());
temp.add(i);
map.put(i,temp);
}
//check for freq 3
for (Map.Entry<Integer,List<Integer>> e : map.entrySet())
{
if(e.getValue().size() == 3)
ans ="YES";
}
//freq 2 and pos change
for (Map.Entry<Integer,List<Integer>> i : map.entrySet())
{
if(i.getValue().size() == 2 && i.getValue().get(0) != i.getValue().get(1) - 1)
ans = "YES";
}
System.out.println(ans);
输入 arr[]
1 2 1
1 2 2 3 2
1 1 2
1 2 2 1
1 1 2 2 3 3 4 4 5 5
产量
YES
YES
NO
YES
NO
但其不能正常工作的目的。请谁能告诉我如何更有效地做到这一点。另外,对于in first循环,我想我可以使用map.merge。如果有人知道如何做,请让我知道。谢谢✌️
首先,下面的片段将指数推送到向量的末尾,你需要在Java中采用同样的方法,而不需要增强for-each循环。
// C++
for (int i=1;i<=n;i++)
idv.[arr[i]].push_back(i);
// Java
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i=0; i<arr.length; i++) {
List<Integer> temp = map.getOrDefault(arr[i], new ArrayList<>());
temp.add(i);
map.put(arr[i],temp);
// or shorter:
// map.computeIfAbsent(arr[i], key->new ArrayList<>()).add(i);
}
其次,你在Java和C++中都迭代了两次映射,这是不需要的。使用相同的逻辑异构。在Java中,你可以只迭代值,如果你不需要键,就不需要迭代实际条目。
for (List<Integer> list: map.values()) {
if (list.size() == 3 || (list.size() == 2 && list.get(0) != list.get(1) - 1)) {
ans = "YES";
break; // no need to continue iteration, you have the answer
}
}
整个过程可以更加简化,利用 涓涓细流 帮助您创建 Map<Integer, List<Integer>>
:
Map<Integer, List<Integer>> map1 = IntStream.range(0, arr.length)
.boxed()
.collect(Collectors.groupingBy(i -> arr[i]));
String ans = "NO";
for (List<Integer> list: map.values()){
if (list.size() == 3 || (list.size() == 2 && list.get(0) != list.get(1) - 1)) {
ans = "YES";
break;
}
}
谢谢 @Holger,这可以更简单地使用 Collectors.collectingAndThen
:
String ans = IntStream.range(0, arr.length)
.boxed()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(i -> arr[i]),
map -> map.values().stream()
.filter(l -> l.size() == 3 || (l.size() == 2 && l.get(0) != l.get(1) - 1))
.findAny().map(x -> "YES").orElse("NO")));