Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to find out if two sorted lists contain same element Java.

I have a tight loop that searches coprimes. A list primeFactors. Its n-th element contains a sorted list of prime decomposition of n. I am checking if c and d are coprimes using checkIfPrimes

boolean checkIfPrimes(int c, int d, List<List<Integer>> primeFactors) {
    List<Integer>  common = new ArrayList<>(primeFactors.get(d)); //slow
    common.retainAll(primeFactors.get(c));        
    return (common.isEmpty());
}

primeFactors.get(d).retainAll(primeFactors.get(c)) looks promising, but it will alter my reusable primeFactors object.

Creating a new object is relatively slow. Is there a way to speed up this step? Can I somehow utilize the fact that lists are sorted? Should I use arrays instead?

like image 311
sixtytrees Avatar asked Jul 08 '16 17:07

sixtytrees


People also ask

How do you check if two elements in a list are the same Java?

The equals() method of List interface compares the specified object with this collection for equality. It returns a Boolean value true if both the lists have same elements and are of the same size.

How do you compare two sorted lists?

We can club the Python sort() method with the == operator to compare two lists. Python sort() method is used to sort the input lists with a purpose that if the two input lists are equal, then the elements would reside at the same index positions.

How can you tell if two Arraylists have the same element?

You can compare two array lists using the equals() method of the ArrayList class, this method accepts a list object as a parameter, compares it with the current object, in case of the match it returns true and if not it returns false.

How do I compare two lists in Java?

Java provides a method for comparing two Array List. The ArrayList. equals() is the method used for comparing two Array List. It compares the Array lists as, both Array lists should have the same size, and all corresponding pairs of elements in the two Array lists are equal.


2 Answers

You could use a Collection with faster lookup - e.g. a Set if you only need the prime factors without repetitions, or a Map if you also need the count of each factor.

Basically, you want to know whether the intersection of two Sets is empty. Oracle Set tutorial shows a way to calculate the intersecton (similar to what you already mentioned, using retainAll on a copy, but on Sets the operation should be more efficient).

like image 54
Hulk Avatar answered Oct 24 '22 15:10

Hulk


Since your lists are relatively small, and this operation is executed very often, you should avoid creating any new Lists or Sets, because it might lead to a significant GC pressure.

The scan linear algorithm is

public static boolean emptyIntersection(List<Integer> sortedA, List<Integer> sortedB) {
    if (sortedA.isEmpty() || sortedB.isEmpty())
        return true;
    int sizeA = sortedA.size(), sizeB = sortedB.size();
    int indexA = 0, indexB = 0;
    int elementA = sortedA.get(indexA), elementB = sortedB.get(indexB);
    while (true) {
        if (elementA == elementB) {
            return false;
        } else if (elementA < elementB) {
            indexA++;
            if (indexA == sizeA)
                return true;
            elementA = sortedA.get(indexA);
        } else {
            // elementB < elementA
            indexB++;
            if (indexB == sizeB)
                return true;
            elementB = sortedB.get(indexB);
        }
    }
}

Also consider using lists of primitive ints instead of boxed integers, e. g. from fastutil library.

like image 41
leventov Avatar answered Oct 24 '22 16:10

leventov