removeAll is now O(n+m) if both lists are sorted

This commit is contained in:
2018-11-20 19:53:33 +01:00
parent 430b4c50ca
commit ee04f21f29
4 changed files with 105 additions and 10 deletions

View File

@@ -17,6 +17,7 @@ import java.util.stream.StreamSupport;
*/
public final class IntList implements Serializable, Cloneable {
// TODO retainAll on sorted lists
// TODO support Iterator
// TODO add mod counts
// TODO support sublists
@@ -433,17 +434,42 @@ public final class IntList implements Serializable, Cloneable {
* This method does not release any memory. Call {@link #trim()} to free unused
* memory.
* <p>
* If {@code retain} is sorted, then the algorithm has a complexity of
* O(n*log(m)), where n is the length of {@code this} and m the length of
* {@code retain}. If {@code retain} is not sorted, then the complexity is
* O(n*m).
* If both lists are sorted, then the algorithms has time complexity of O(n+m),
* where n is the length of {@code this} and m the length of {@code remove}. If
* only {@code remove} is sorted, then the algorithm has a complexity of
* O(n*log(m)). If {@code remove} is not sorted, then the complexity is O(n*m).
* The space complexity is constant in all cases.
*
* @param remove the elements to remove
* @throws NullPointerException if the specified {@link IntList} is null
* @see #trim()
*/
public void removeAll(final IntList remove) {
removeIf((val, index) -> remove.indexOf(val) >= 0);
if (isSorted() && remove.isSorted()) {
removeSorted(remove);
} else {
removeIf((val, index) -> remove.indexOf(val) >= 0);
}
}
private void removeSorted(final IntList remove) {
int posInRemoveList = 0;
int insertPosition = 0;
for (int i = 0; i < size; i++) {
final int current = data[i];
while (posInRemoveList < remove.size() && remove.get(posInRemoveList) < current) {
posInRemoveList++;
}
if (posInRemoveList >= remove.size() || remove.get(posInRemoveList) != current) {
// keep current element
data[insertPosition] = current;
insertPosition++;
}
}
size = insertPosition;
}
/**

View File

@@ -423,17 +423,42 @@ public final class LongList implements Serializable, Cloneable {
* This method does not release any memory. Call {@link #trim()} to free unused
* memory.
* <p>
* If {@code retain} is sorted, then the algorithm has a complexity of
* O(n*log(m)), where n is the length of {@code this} and m the length of
* {@code retain}. If {@code retain} is not sorted, then the complexity is
* O(n*m).
* If both lists are sorted, then the algorithms has time complexity of O(n+m),
* where n is the length of {@code this} and m the length of {@code remove}. If
* only {@code remove} is sorted, then the algorithm has a complexity of
* O(n*log(m)). If {@code remove} is not sorted, then the complexity is O(n*m).
* The space complexity is constant in all cases.
*
* @param remove the elements to remove
* @throws NullPointerException if the specified {@link LongList} is null
* @see #trim()
*/
public void removeAll(final LongList remove) {
removeIf((val, index) -> remove.indexOf(val) >= 0);
if (isSorted() && remove.isSorted()) {
removeSorted(remove);
} else {
removeIf((val, index) -> remove.indexOf(val) >= 0);
}
}
private void removeSorted(final LongList remove) {
int posInRemoveList = 0;
int insertPosition = 0;
for (int i = 0; i < size; i++) {
final long current = data[i];
while (posInRemoveList < remove.size() && remove.get(posInRemoveList) < current) {
posInRemoveList++;
}
if (posInRemoveList >= remove.size() || remove.get(posInRemoveList) != current) {
// keep current element
data[insertPosition] = current;
insertPosition++;
}
}
size = insertPosition;
}
/**