Given your description, I don’t think your code is right:
check which elements of the list p
have value >= the list values q
. If available, I need to store the position (index + 1) of each item in another list. However, this third list may only have a quantity of elements <= the value k
I tested your code with the lists below:
List<Integer> p = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 90);
List<Integer> q = Arrays.asList(10, 20, 30, 40, 50);
System.out.println(kthPerson(3, p, q));
And the result was:
[3, 4, 5, 6, 7]
Only the heading 3 (corresponding to index 2) of p
is number 30, which is no higher than the values of q
(since q
has values 40 and 50, which are greater than 30). In addition, the result has 5 elements, which is greater than k
.
Anyway, it wasn’t very clear what to do. I understood two ways:
- verify the elements of
p
which are larger than all the elements of q
- verify the elements of
p
which are larger than the element of q
who is in the same position
We will see solutions for each case.
Option 1
If the idea is to check the elements of p
which are larger than all the elements of q
, so you don’t have to go through q
several times. Just find the biggest element of q
and check which elements of p
are larger or equal to it. Then just take the first k
elements and return to list:
public static List<Integer> kthPersonOpcao1Stream(int k, List<Integer> p, List<Integer> q) {
// encontrar o maior elemento de q
int maxQ = Collections.max(q);
return IntStream
// iterar pelos índices de p
.range(0, p.size())
// pegar os elementos maiores ou iguais a maxQ
.filter(i -> p.get(i) >= maxQ)
// pegar somente os k primeiros
.limit(k)
// somar 1 ao índice
.map(i -> i + 1)
// converter os valores int para Integer
.boxed()
// coletar os valores em uma List
.collect(Collectors.toList());
}
But if the concern is performance, maybe you shouldn’t use streams, since they are slower than a loop traditional. Of course for a few small lists it won’t make that much difference, but anyway, the solution without stream it would be quite simple:
public static List<Integer> kthPersonOpcao1Loop(int k, List<Integer> p, List<Integer> q) {
int maxQ = Collections.max(q);
List<Integer> result = new ArrayList<>();
for (int i = 0; i < p.size() && result.size() < k; i++) {
if (p.get(i) >= maxQ) {
result.add(i + 1);
}
}
return result;
}
Notice the condition of for
(i < p.size() && result.size() < k
), which checks whether I have compared all the elements of p
and whether the list of results has k
elements. Thus it already covers also the cases in which are found less than k
elements (as k
is the maximum size that the results list can have, but nothing guarantees that you will always find k
elements).
Option 2
If the idea is to compare each element of p
with the element of q
which is in the same position, first we need to know which of the lists is smaller (for example, if p
has 10 elements and q
has 4, I do not need to check the 10 elements of p
, just check the first 4).
The code is very similar to option 1, the difference is that instead of comparing the elements of p
with the greatest element of q
, I compare only with those in the same position:
// com stream
public static List<Integer> kthPersonOpcao2Stream(int k, List<Integer> p, List<Integer> q) {
// só preciso iterar até o tamanho da menor das listas
int size = Math.min(p.size(), q.size());
return IntStream
// iterar pelos índices até "size"
.range(0, size)
// pegar os elementos de p maiores ou iguais ao elemento de q na mesma posição
.filter(i -> p.get(i) >= q.get(i))
// pegar somente os k primeiros
.limit(k)
// somar 1 ao índice
.map(i -> i + 1)
// converter os valores int para Integer
.boxed()
// coletar os valores em uma List
.collect(Collectors.toList());
}
// sem stream
public static List<Integer> kthPersonOpcao2Loop(int k, List<Integer> p, List<Integer> q) {
int size = Math.min(p.size(), q.size());
List<Integer> result = new ArrayList<>();
for (int i = 0; i < size && result.size() < k; i++) {
if (p.get(i) >= q.get(i)) {
result.add(i + 1);
}
}
return result;
}
@Marcosantion I saw your question and the answers. Thank you for recommending the link. How did you remove the repeated cases? You implemented using for nested or used stream?
– Yan