Учитывая это -
Напишите метод, который принимает массив int размером m ...
Полагаю, справедливо будет заключить, что существует верхний предел для m, равный величине наибольшего int (типично 2 ^ 32). Другими словами, даже если m не задано как int, тот факт, что массив не может иметь дубликаты, подразумевает, что не может быть больше, чем число значений, которые вы можете сформировать из 32 битов, что, в свою очередь, подразумевает, что m ограничено, чтобы быть также int.
Если такой вывод приемлем, тогда я предлагаю использовать фиксированное пространство (2 ^ 33 + 2) * 4 байта = 34 359 738 376 байтов = 34,4 ГБ для обработки всех возможных случаев. (Не считая места, требуемого входным массивом и его циклом).
Конечно, для оптимизации я бы сначала учел m и выделил только фактическую необходимую сумму (2m + 2) * 4 байта.
Если это приемлемо для ограничения пространства O (1) - для поставленной задачи - тогда позвольте мне перейти к алгоритмическому предложению ...:)
Допущения : массив из m целых, положительных или отрицательных, ни один из которых не превышает 4 байта. Дубликаты обрабатываются. Первое значение может быть любым допустимым int. Ограничьте м, как указано выше.
Сначала , создайте массив int длиной 2m-1, ary и предоставьте три переменные int: left , diff и вправо . Обратите внимание, что составляет 2 м + 2 ...
Second , возьмите первое значение из входного массива и скопируйте его в позицию m-1 в новом массиве. Инициализируйте три переменные.
- набор все [м-1] - nthVal // n = 0
- set left = diff = right = 0
Третий , переберите оставшиеся значения во входном массиве и сделайте следующее для каждой итерации:
- set diff = nthVal - ary [m-1]
- if ( diff > m-1 + right || diff <1-m + <strong>left ) return false // вне границ
- if ( ary [m-1 + diff ]! = Null) вернуть false // duplicate
- set ary [m-1 + diff ] = nthVal
- if ( diff > left ) left = diff // ограничивает левую границу дальше вправо
- if ( diff <<strong> right ) right = diff // ограничивает правую границу дальше влево
Я решил поместить это в код, и это сработало.
Вот рабочий пример с использованием C #:
public class Program
{
static bool puzzle(int[] inAry)
{
var m = inAry.Count();
var outAry = new int?[2 * m - 1];
int diff = 0;
int left = 0;
int right = 0;
outAry[m - 1] = inAry[0];
for (var i = 1; i < m; i += 1)
{
diff = inAry[i] - inAry[0];
if (diff > m - 1 + right || diff < 1 - m + left) return false;
if (outAry[m - 1 + diff] != null) return false;
outAry[m - 1 + diff] = inAry[i];
if (diff > left) left = diff;
if (diff < right) right = diff;
}
return true;
}
static void Main(string[] args)
{
var inAry = new int[3]{ 2, 3, 4 };
Console.WriteLine(puzzle(inAry));
inAry = new int[13] { -3, 5, -1, -2, 9, 8, 2, 3, 0, 6, 4, 7, 1 };
Console.WriteLine(puzzle(inAry));
inAry = new int[3] { 21, 31, 41 };
Console.WriteLine(puzzle(inAry));
Console.ReadLine();
}
}