@New-Developer
Изучаю JavaScript

Как исправить функцию?

Функция выдает комбинацию чисел массива для получения следующего большего числа. Элементы массива могут состоять из 1 или 2 цифр.
Для массивов, в которых есть одно число из 1 цифры и следующее из 2 цифр этого числа, функция выдает неправильный результат. Как ее исправить ? Нужно решить без генерации всех перестановок в массиве.
function nextBigger(n) {
  let rev = n.reverse(),
    id1 = rev.findIndex((v, i)=>i>0 && `${v}${rev[i-1]}`<`${rev[i-1]}${v}`);
  if (id1 < 0) return id1;
  let id2 = rev.findIndex(v => `${v}${rev[id1]}` > `${rev[id1]}${v}`);
  if (id2 < 0) return id2;
  [rev[id1], rev[id2]] = [rev[id2], rev[id1]];
  return rev.slice(id1).reverse().concat(rev.slice(0, id1))
}
console.log(+nextBigger([9, 1, 3, 60, 1, 72, 9, 2]).join(''))
9136019272  // правильно
console.log(+nextBigger([24, 1, 11, 26]).join(''))
2412611  // неправильно
  • Вопрос задан
  • 290 просмотров
Решения вопроса 2
Aleksandr-JS-Developer
@Aleksandr-JS-Developer
Лучше проще, чем никогда
Задачка интересная)
Не знаю насчёт сложности, я разбираюсь поверхностно, но думаю, что в моей реализации точно будет от O(n^2).
Наверняка можно было решить и лучше, но мне лень))
Кстати, не проверял его на коротеньких массивах и аномально длинных.
Да и вообще, за пределы inputArr0, inputArr1 и inputArr2 не выходил, так что проверяйте сами, нечего бездельничать.
code

const inputArr0 = [9, 1, 3, 60, 1, 72, 9, 2]; // 9136019272
const inputArr1 = [55, 1, 11, 2]; // 551121
const inputArr2 = [24, 1, 11, 26]; // 2411261

const foo = arr => {
  const currSum = +arr.join('');
  let rez = '';
  const sumes = [];
  
  for( let i = 1; i < arr.length+1; i++ ){
    const arrClone = [...arr];
    const lastIElems = arrClone.splice(i*-1, 1);
    const reduced = lastIElems.reduce((a, c) => {
      const num = a + c;
      const secNum = c + a;
      
      return +num > +secNum ? num : secNum;
    }, '');
    
    rez = arrClone.join('')+reduced;
    
    if( +rez > currSum ){
      sumes.push(rez);
     }
  }

  return String( Math.min(...sumes) );
}

console.log( +foo(inputArr0) === 9136019272 ); // true
console.log( +foo(inputArr1) === 551121 ); // true
console.log( +foo(inputArr2) === 2411261 ); // true


код на JSFiddle
Ответ написан
VlasenkoFedor
@VlasenkoFedor
Программист: php, js, go
const nextBigger = arr => {
    const num = arr.join('');
    const max = arr.sort((a, b) => b - a).join('');
    const tpl = ''.padStart(arr.length, '-')
    const check = str => {
        arr.forEach(v => str = str.replace(v, '-'))
        return str === tpl
    }
    if (max === num) return -1;
    let n = +num;
    while (true) {
        n += 9
        if (check(n.toString())) return n
    }
}

это решение основано на приведенной задаче в качестве примера
здесь результатом является строка
результатом [21, 1, 2, 12, 11] ->21122111 может быть несколько
[21, 12, 2, 1, 11], [21, 12, 2, 11, 1] ...
нужно преобразовать строку результата в массив, сами напишите
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы