Используя реализации библиотеки, это можно немного ускорить. Использование настроенных коллекций может сделать это еще быстрее, но здесь это выходит за рамки. Вы столкнулись с определенными итерационными ограничениями, поэтому в любом случае вы можете сделать так много.
Будет полезно разбить процедуру на более мелкие методы:
public static void decrementColumns(List<List<Integer>> rows, List<Boolean> mask) {
final List<Integer> maskIndicies = getMaskIndicies(mask);
// We're locked into this iteration because we have to modify every row.
for (List<Integer> row : rows) {
apply(maskIndicies, row);
}
}
// Your big savings will come from figuring out the indicies.
// This allows us to make the iterations-per-row smaller -
// assuming not every row (or even most) is set to 'true'!
public static List<Integer> getMaskIndicies(List<Boolean> mask) {
final List<Integer> maskIndicies = new ArrayList<Integer>(mask.size());
for (int i = 0; i < mask.size(); i++) {
if (mask.get(i)) {
maskIndicies.add(i);
}
}
}
public static void apply(List<Integer> maskIndicies, List<Integer> row) {
// We're locked into this iteration, needing to apply the transformation
// to every column included.
for (Integer index : maskIndicies) {
final Integer modified = row.get(index) - 1;
row.set(index, modified);
}
}
Обратите внимание, что это НЕ потокобезопасный, поэтому будьте осторожны. Я также не писал никаких проверок безопасности, так что ...
<ч />
РЕДАКТИРОВАТЬ:
Перечитав вопрос, я понял, что изначально неправильно прочитал, что делал код (и я бью себя - почему-то я пропустил цикл).
Пересмотренная версия:
public static void decrementColumns(List<List<Integer>> rows, List<Boolean> mask) {
final int count = getMaskCount(mask);
// We're locked into this iteration because we have to modify every row.
for (List<Integer> row : rows) {
apply(row, count);
}
}
public static void int getMaskCount(List<Boolean> mask) {
int count = 0;
for(Boolean flag : mask) {
if (!flag) {
count++;
}
}
return count;
}
public static void apply(List<Integer> row, int count) {
for (int index = 0; index < row.size(); index++) {
final Integer modified = row.get(index) - count;
row.set(index, modified);
}
}
Обратите внимание, что это все еще не выполняет ~ именно то, что делает ваш исходный код, а только то, что, как я предполагаю, вы пытаетесь сделать, учитывая текст «требований». Во-первых, вы определяете как минимум 2 дополнительный список, для которого вы не задаете отношения - один из которых, я уверен, является опечаткой. Если вы отредактируете свой вопрос для ясности, я смогу дать лучший ответ; между вашим кодом и текстом вопроса происходит несколько двусмысленных или противоречивых вещей. Обратите внимание, что хотя ваш исходный код работает в O(m * (n ^ 2))
, минимум (и моя версия) работает в O(n + (m * n))
.