Я решал задачу по лит-коду № 553 (просто учился), и у меня возникли проблемы с ограничениями по времени. Я передал свой код ChatGPT, чтобы узнать, как его оптимизировать, и он дал мне этот код:
public bool CheckSubArraySumV2(int[] nums, int k)
{
if (nums.Length < 2) return false;
Dictionary<int, int> sums = new()
{
[0] = -1
};
int sum = 0;
for(int i = 0; i < nums.Length; i++)
{
sum += nums[i];
int remain = sum % k;
if (sums.ContainsKey(remain))
{
if (i - sums[remain] > 1)
{
return true;
}
}
else{
sums[remain] = i;
}
}
return false;
}
После того, как я понял этот метод, я скопировал все, кроме этого вложенного оператора if:
if (sums.ContainsKey(remain))
{
if (i - sums[remain] > 1)
{
return true;
}
}
Я изменил это на это:
if (sums.ContainsKey(remain) && i - sums[remain] > 1)
{
return true;
}
но по какой-то причине в тестовом примере с nums = [5,0,0,0] и k = 3 я получил неправильный ответ (false вместо true).
После нескольких попыток я решил заменить && back на вложенный оператор if, и по какой-то причине это работало нормально.
Мой вопрос: в чем разница между проверкой условия «&&» и вложенным оператором if? Разве он не работает от короткого замыкания?





Если бы не ветка else, ваш рефакторинг был бы правильным, но существование else меняет дело.
В исходном коде сначала оценивается условие sums.ContainsKey(remain). Если это false, выполняется ветвь else.
После замены вложенных if на составное условие с && значение меняется — сначала оценивается sums.ContainsKey(remain). Если это false, блок else выполняется — пока все хорошо. Однако если это true, то оценивается условие i - sums[remain] > 1, а если false, то все составное выражение также false, поэтому ветвь else снова выполняется.
Если внимательно посмотреть на код, рассматривая эти случаи более широким взглядом
Дело 1
if (sums.ContainsKey(remain)) {
if (i - sums[remain] > 1) {
return true;
}
} else {
sums[remain] = i;
}
Случай 2
if (sums.ContainsKey(remain) && i - sums[remain] > 1) {
return true;
} else {
sums[remain] = i;
}
Вы поймете, что в первом случае код перейдет в блок else только в том случае, если нижеприведенное условие верно.
sums.ContainsKey(остается)
Во втором случае код все равно будет переходить в условие else, если вышеуказанное условие не выполнено, но из-за условия && if
я - суммы [остаются] > 1
результаты ложны, тогда код также перейдет в условие else, но если это условие не выполнено в случае 1, ничего не произойдет.
я не обратил внимания, спасибо