Отсутствует и повторяется массив чисел от 1... n для очень больших входов. Решение с использованием свойств серии 1... n. Проблемы с переполнением

63
6

Это код, предоставленный https://www.interviewbit.com/problems/repeat-and-missing-number-array/ на том же сайте:

vector<int> repeatedNumber(const vector<int> &V) {
long long sum = 0;
long long squareSum = 0;
long long temp;
for (int i = 0; i < V.size(); i++) {
temp = V[i];
sum += temp;
sum -= (i + 1);
squareSum += (temp * temp);
squareSum -= ((long long)(i + 1) * (long long)(i + 1));
}
// sum = A - B
// squareSum = A^2 - B^2 = (A - B)(A + B)
// squareSum / sum = A + B
squareSum /= sum;

// Now we have A + B and A - B. Lets figure out A and B now.
int A = (int) ((sum + squareSum) / 2);
int B = squareSum - A;

vector<int> ret;
ret.push_back(A);
ret.push_back(B);
return ret;
}

Теперь я написал аналогичный код, но без typecasting, и он возвратил ошибки для больших входов. Может ли кто-нибудь объяснить, как типизация решает переполнение?

Кроме того, я видел метод XOR для этого вопроса, но я не знаю о проблемах с манипуляциями с битами. Было бы здорово, если бы кто-то помог мне с некоторыми ссылками/ресурсами для обработки вопросов, используя подход манипулирования бит!

Спасибо, что прочитал мою проблему и хочу помочь! Ура!

спросил(а) 2021-01-25T15:22:21+03:00 5 месяцев назад
1
Решение
64

(i + 1) * (i + 1) будет оцениваться в int арифметике с потенциалом переполнения, поведение которого не определено.

Пишу

((long long)(i + 1) * (long long)(i + 1)); 

это длинный способ устранения этого эффекта; вы можете использовать более четкие

(i + 1LL) * (i + 1)

вместо этого, что вызывает преобразование других терминов.

ответил(а) 2021-01-25T15:22:21+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема