Java 具有重复项的前K个元素
我在寻找一种方法来确定数组中包含重复值的前K个元素 假设这里有一个数组{1,2,2,3,5,2,6,4,5,2,6,3,5} 我需要确定此数组中前两个最大元素(第一大和第二大)的索引: i、 e.结果应为{4,6,8,10,12}->6为最大元素,5为第二大元素Java 具有重复项的前K个元素,java,algorithm,sorting,Java,Algorithm,Sorting,我在寻找一种方法来确定数组中包含重复值的前K个元素 假设这里有一个数组{1,2,2,3,5,2,6,4,5,2,6,3,5} 我需要确定此数组中前两个最大元素(第一大和第二大)的索引: i、 e.结果应为{4,6,8,10,12}->6为最大元素,5为第二大元素 谢谢。你真的可以做点什么 与编写查找最大值的代码类似: int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5}; int topvalue=Integer.MIN_VALUE; for(int
谢谢。你真的可以做点什么 与编写查找最大值的代码类似:
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
int topvalue=Integer.MIN_VALUE;
for(int i=0;i<array.length;i++) {
int v=array[i];
if(v>topvalue)
topvalue=v;
}
System.out.println(topvalue);
(作为价值)
然后扩展它以收集topvalue
的索引(这就是为什么使用索引循环是个好主意)。这意味着要做一些小的更改,比如不仅要搜索更大的值,还要收集当前最大值的引用。如果出现新的最大值,则可以丢弃旧指数:
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
int topvalue=Integer.MIN_VALUE;
List<Integer> topindices=new ArrayList<>();
for(int i=0;i<array.length;i++) {
int v=array[i];
if(v>topvalue) {
topvalue=v;
topindices.clear();
}
if(v==topvalue)
topindices.add(i);
}
System.out.println(topindices);
(指数)
然后把它改成2。这意味着,如果遇到新的最大值,则不会丢弃前一个值,而是将其作为第二大值传递(值及其索引,并为最大的索引启动新集合)。如果你遇到一个介于最大值和第二大值之间的值,那将是新的第二大值,有一个新的索引集合。代码变得有点毛茸茸,但变化并不严重:
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
int topvalue=Integer.MIN_VALUE;
int top2value=Integer.MIN_VALUE;
List<Integer> topindices=new ArrayList<>();
List<Integer> top2indices=new ArrayList<>();
for(int i=0;i<array.length;i++) {
int v=array[i];
if(v>topvalue) {
top2value=topvalue;
top2indices=topindices;
topvalue=v;
topindices=new ArrayList<>();
}else if(v!=topvalue && v>top2value) {
top2value=v;
top2indices.clear();
}
if(v==topvalue)
topindices.add(i);
else if(v==top2value)
top2indices.add(i);
}
System.out.print(topindices);
System.out.println(top2indices);
topindices.addAll(top2indices);
topindices.sort(null);
System.out.println(topindices);
(第一行是TopIndexs
,然后是Top2Indicates
,第二行是addAll()
和sort()
的结果)
虽然用于更新索引的单独的if(==)
s很有吸引力,但为了使事情更具规模,一次运行零个或正好一个条件块会更方便,因为在一般情况下,将有一个循环,如果所有事情都发生在一个块中,它可以简单地中断。因此,上面的代码需要一个位重组,它复制了一些代码(即add()
s,但简化了if
条件)clear()
也变成了创建一个新列表,因为使用这种方法,我们不必考虑列表被传递(在这种情况下,clear()
和重用会毁掉一切):
如果你称之为
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
for(int k=1;k<=3;k++)
topk(array,k);
(它还显示单独和合并的排序变体,只是在第一种情况下它们是相同的)您尝试过什么吗?你在某个特定的问题上卡住了吗?另外,结果不应该是{4,6,8,10,12}
?这有帮助吗?一个for
循环、max1-list1
、max2-list2
和一些if
-s突然出现在我的脑海中。下面是一个如何非常容易地完成的快速概述:1)从数组中提取最大和第二大的数字。这可以通过for循环中的一些简单整数比较来完成。2) 再次迭代列表,现在检查(1)中提取的值是否与当前值匹配。如果它们匹配,则将当前索引保存在某个集合中(例如列表
)。3) 完成了。如果你自己表现出一些努力,人们会更愿意帮助你,因为这表明你不只是希望你的任务为你完成。不,这不是为了任务。对于一个没有重复的简单工作流,我考虑使用minHeap。我只是不能理解这样一种情况,即复制品也应该被考虑在内,所以我想让其他人看到我的观点。我总是试图在Ideone上添加完整的示例,但不知何故,今天我甚至不能System.out.println(“Hello World”)代码>在那里,它会因未指定的编译错误而消亡,有时还会出现运行时错误(也没有详细信息)。
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
int topvalue=Integer.MIN_VALUE;
int top2value=Integer.MIN_VALUE;
List<Integer> topindices=new ArrayList<>();
List<Integer> top2indices=new ArrayList<>();
for(int i=0;i<array.length;i++) {
int v=array[i];
if(v>topvalue) {
top2value=topvalue;
top2indices=topindices;
topvalue=v;
topindices=new ArrayList<>();
}else if(v!=topvalue && v>top2value) {
top2value=v;
top2indices.clear();
}
if(v==topvalue)
topindices.add(i);
else if(v==top2value)
top2indices.add(i);
}
System.out.print(topindices);
System.out.println(top2indices);
topindices.addAll(top2indices);
topindices.sort(null);
System.out.println(topindices);
[6, 10][4, 8, 12]
[4, 6, 8, 10, 12]
for(int i=0;i<array.length;i++) {
int v=array[i];
if(v>topvalue) {
top2value=topvalue; // passing down
top2indices=topindices;
topvalue=v; // initialization
topindices=new ArrayList<>();
topindices.add(i);
}else if(v==topvalue) {
topindices.add(i); // update only
}else if(v>top2value) {
top2value=v; // initialization only
top2indices=new ArrayList<>();
top2indices.add(i);
}else if(v==top2value)
top2indices.add(i); // update only
}
static void topk(int[] array,int k) {
int[] topvalues=new int[k];
List<Integer>[] topindices=new List[k];
for(int i=0;i<k;i++) {
topvalues[i]=Integer.MIN_VALUE;
topindices[i]=new ArrayList<>();
}
for(int i=0;i<array.length;i++) {
int v=array[i];
for(int j=0;j<k;j++)
if(v>topvalues[j]) {
for(int t=k-1;t>j;t--) {
topvalues[t]=topvalues[t-1];
topindices[t]=topindices[t-1];
}
topvalues[j]=v;
topindices[j]=new ArrayList<>();
topindices[j].add(i);
break;
}else if(v==topvalues[j]) {
topindices[j].add(i);
break;
}
}
System.out.println("topk("+k+")");
for(List<Integer> i:topindices)
System.out.print(i);
System.out.println();
for(List<Integer> i:topindices)
if(i!=topindices[0])
topindices[0].addAll(i);
topindices[0].sort(null);
System.out.println(topindices[0]);
}
int[] array=new int[] {1,2,2,3,5,2,6,4,5,2,6,3,5};
for(int k=1;k<=3;k++)
topk(array,k);
topk(1)
[6, 10]
[6, 10]
topk(2)
[6, 10][4, 8, 12]
[4, 6, 8, 10, 12]
topk(3)
[6, 10][4, 8, 12][7]
[4, 6, 7, 8, 10, 12]