英文:
Best Algorithm to avoid nested loops without Brute Force approach
问题
I want to make this method run as fast as possible.
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int k =4.
void nestLoop(){
for(int i = 0; i < q.length; i++){
for(int j = 0; j < p.length; j++){
//code continues
// inside here...
//This approach
// takes a longer
//time to finish
// executing. I need a better algorithm
}
}
}
To be clearer; at q[0], p = 1, since 1 is less than q[0], choose 1, and p[4] is also lower, choose 1; hence the answer when it is q[0] are 1 and 1 : but because 1 and 1 are two ints, they are not equal to k = 4, then return 0. If the answer had been 1, 1,1,1 then the number is 4 which is equal to k. [1,1,1,1] will be returned. The same for other q and so on
英文:
I want to make this method run as fast as possible.
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int k =4.
void nestLoop(){
for(int i = 0; i < q.length; i++){
for(int j = 0; j < p.length; j++){
//code continues
// inside here...
//This approach
// takes a longer
//time to finish
// executing. I need a better algorithm
}
}
}
To be clearer; at q[0], p = 1, since 1 is less than q[0], choose 1, and p[4] is also lower, choose 1; hence the answer when it is q[0] are 1 and 1 : but because 1 and 1 are two ints, they are not equal to k = 4, then return 0. If the answer had been 1, 1,1,1 then the number is 4 which is equal to k. [1,1,1,1] will be returned. The same for other q and so on
答案1
得分: 2
如果我理解正确,您要返回的要么是 k 或 0,对吗?
然后这是实现方式:
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int k = 4;
void notNested()
{
TreeSet<Integer> ts = new TreeSet<Integer>();
// 在数组中找到第 k 小的数字。
PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
for (int p1 : p)
{
if (pq.size() < k)
{
pq.add(p1);
} else if (pq.peek() > p1)
{
pq.poll();
pq.add(p1);
}
}
int ksm = pq.poll();
// 对于每个 q,只与第 k 小的数字比较。
for (int q1 : q)
{
if (q1 >= ksm)
{
results.add(k);
}
else
{
results.add(0);
}
}
}
请注意,代码中有一个错误,int k =4.
应该改为 int k = 4;
,修正了这个错误后,代码应该正常运行。
英文:
If I understand correctly you are returning either k or 0, correct?
Then this is the way to do it:
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int k =4.
void notNested()
{
TreeSet<Integer> ts = new TreeSet<Integer>();
// Find the kth smallest number in the array.
PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
for (int p1 : p)
{
if (pq.size() < k)
{
pq.add(p1);
} else if (pq.peek() > p1)
{
pq.poll();
pq.add(p1);
}
}
int ksm = pq.poll();
// For each q, compare against kth smallest only.
for (int q1 : q)
{
if (q1 >= ksm)
{
results.add(k);
}
else
{
results.add(0);
}
}
}
答案2
得分: 1
如果p
中的不同元素数量相对较小,与总元素数量相比,以下方法可能有效。然而,如果有许多不同元素,甚至所有元素都不同,那么它将变得更慢。
- 创建一个将元素映射到它们的索引的
Map
,例如[1,4,4,5,1,3,6]
将变为{1: [0,4], 4: [1,2], 5: [3], 3: [5], 6: [6]}
- 从该映射中,获取所有小于
q
中当前元素的元素的索引列表 - 将它们放入一个堆或优先队列中,按照该元素的下一个未使用的索引进行排序
- 从堆中弹出列表,获取第一个索引,并将它们放回堆中以获取下一个索引,直到获得
k
个索引
如果有许多重复的元素(仅在这种情况下),这可能会略微降低复杂度。对于p
中的P
个元素,其中有d
个不同元素,在q
中有Q
个元素,并且有k
个操作,这应该具有复杂度O(P + Q*(d+k*log(d)))
(P
用于创建映射,d
用于选择列表和k
堆操作,log(d)
用于所有Q
个查询)。
英文:
If the number of different elements in p
is relatively small compared to the total number of elements, the following might work. If, however, there are many different elements, or even all elements are different, then it will be much slower.
- create a
Map
mapping elements to their indices, e.g.[1,4,4,5,1,3,6]
would become{1: [0,4], 4: [1,2], 5: [3], 3: [5], 6: [6]}
- from that map, get the lists of indices for all elements smaller than the current element from
q
- put those into a Heap, or Priority Queue, sorted by the next unused index for that element
- pop lists from the heap, get the first index, and put them back onto the heap for the next index until you get
k
indices
If there are many repeated elements (and only then), this may somewhat reduce the complexity. For P
elements in p
, d
of which being distinct, Q
elements in q
, and k
, this should have complexity of O(P + Q*(d+k*log(d)))
(P
for creating the map, and d
for selecting the lists and k
heap operation with log(d)
for all the Q
queries).
答案3
得分: 1
这是一个使用Java Streams的解决方案:
package javaapplication3;
import java.util.Arrays;
import java.util.stream.*;
public class JavaApplication3 {
public static void main(String[] args) {
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int[][] results = new int[q.length][]; // 用于存储结果的数组
int k = 4;
// 对于每个元素 q[i],并行执行
IntStream.range(0, q.length).parallel().forEach(i -> {
final int qi = q[i];
// 获取 p 中不大于 q[i] 的前 k 个元素
results[i] = Arrays.stream(p).filter(v -> v <= qi).limit(k).toArray();
});
for(int i=0; i<q.length; i++) {
int[] result = results[i];
System.out.print("Values less or equal than " + q[i] + ": {");
for (int v : result)
System.out.print(" " + v);
System.out.println(" }");
}
}
}
输出:
Values less or equal than 2: { 1 1 }
Values less or equal than 1: { 1 1 }
Values less or equal than 3: { 1 1 3 }
Values less or equal than 1: { 1 1 }
Values less or equal than 6: { 1 4 4 5 }
Values less or equal than 4: { 1 4 4 1 }
Values less or equal than 3: { 1 1 3 }
注意:你可以选择对 p 进行排序,这会在 p 很大且 k 很小时提高性能。
英文:
This is a solution using Java Streams:
package javaapplication3;
import java.util.Arrays;
import java.util.stream.*;
public class JavaApplication3 {
public static void main(String[] args) {
int[] p = new int[] {1,4,4,5,1,3,6};
int[] q = new int[] {2,1,3,1,6,4,3};
int[][] results = new int[q.length][]; // Array of arrays to store results
int k =4;
// For each element q[i], execute in parallel
IntStream.range(0, q.length).parallel().forEach(i -> {
final int qi = q[i];
// Get first k elements of p <= q[i]
results[i] = Arrays.stream(p).filter(v -> v <= qi).limit(k).toArray();
});
for(int i=0; i<q.length; i++) {
int[] result = results[i];
System.out.print("Values less or equal than " + q[i] + ": {");
for (int v : result)
System.out.print(" " + v);
System.out.println(" }");
}
}
}
Output:
Values less or equal than 2: { 1 1 }
Values less or equal than 1: { 1 1 }
Values less or equal than 3: { 1 1 3 }
Values less or equal than 1: { 1 1 }
Values less or equal than 6: { 1 4 4 5 }
Values less or equal than 4: { 1 4 4 1 }
Values less or equal than 3: { 1 1 3 }
Note: You can optionally sort p which will improve performance if p is large and k is small.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论