找到最小的-Codewars挑战-Javascript

时间:2019-06-25 01:58:58

标签: javascript arrays sorting numbers

尝试解决此Codewars challenge

  

您有一个由数字组成的正数n。您最多可以执行一个操作:选择数字中的一个数字的索引,删除该数字在该索引处,然后将其重新插入数字中的另一个或相同位置,以查找可以获取的最小数字。 / p>      

任务:使用以下语言返回数组,元组或字符串(取决于语言)(请参见“样本测试”):

     

1)最小的数字

     

2)您所取数字d的索引i,i尽可能小

     

3)索引j(尽可能小),您可以在其中插入此数字d以使其具有最小的数字。

示例:

smallest(261235) --> [126235, 2, 0] or (126235, 2, 0) or "126235, 2, 0"

其他示例:

209917, [29917, 0, 1]
285365, [238565, 3, 1]
269045, [26945, 3, 0]
296837, [239687, 4, 1]

因此,为了获得尽可能小的数字,我们将要从数字中删除最小的数字,并将其放在数字的前面,对吗?

function smallest (n) {
  //turn n into an array
  let array = String(n).split("").map(Number);
  
  let smallest = Math.min(...array);
  
  //find index of smallest in original array
  let index = array.indexOf(smallest);
  
  //remove smallest from original array, move it to front
  array.splice(index, 1);
  array.unshift(smallest);
  let newNumber = Number(array.join(""));

  //return array of new number, index of where the smallest was, 
  //and index of where the smallest is now
  return ([newNumber, index, 0]);
}
console.log(smallest(239687));

我的答案是返回正确的数字,但是大约一半的时间,它没有返回正确的索引i和索引j

编辑:最新尝试:

function smallest (n) {

  let array = Array.from(String(n)).map(Number);
  let original = Array.from(String(n)).map(Number);
  let sorted = Array.from(String(n)).map(Number).sort((a, b) => a - b);

  let swapValueOne = [];
  let swapValueTwo = [];

  for (let i = 0; i < array.length; i++) {
    if (array[i] !== sorted[i]) {
      swapValueOne.push(sorted[i]);
      swapValueTwo.push(original[i]);
      break;
    }
  }

  swapValueOne = Number(swapValueOne);
  swapValueTwo = Number(swapValueTwo);
  
  let indexOne = original.indexOf(swapValueOne);
  let indexTwo = original.indexOf(swapValueTwo);

  //remove swapValue
  array.splice(indexOne, 1);
  //insert swapValue
  array.splice(indexTwo, 0, swapValueOne);

  return ([Number(array.join("")), indexOne, array.indexOf(swapValueOne)]);

}

console.log(smallest(296837));

^有时它会给出带有正确交换索引的正确数字,有时数字和交换索引都错误。

3 个答案:

答案 0 :(得分:2)

将最小的元素放在最前面(我们称其为“贪心”解决方案)不是最佳选择。与上一个测试用例一样,考虑n = 296837的情况。您的代码返回[296837, 0, 0],因为它发现2是最小的数字,并将其移到最前面(实际上什么也没做)。如您的示例所示,有一个更好的方法:[239687, 4, 1],即将3移到数组中的第一个索引。

您需要重新制定策略,使其不贪心以找到全局最优值。

如果仍然遇到问题,可以尝试以下操作:

  

数字不能包含很多数字的 –为什么不尝试所有可能的交换?

答案 1 :(得分:1)

这里有个小主意可能会有所帮助。

如果您输入的数字是:

239687

您可以使用的最小数字是排序的数字:

236789

在原始编号中,2和3已经在正确的位置。如果从数字和排序后的数字的左侧开始,则发现的第一个区别就是需要交换的数字。需要将其与已排序列表中的相应数字交换:

orig   2 3 9 6 8 7 -- 6 needs to go before 9
       | | x       
sorted 2 3 6 7 8 9

下一个排序数字为6,但原始数字为9。您需要在9之前插入6。

对于算法,您可以对数字进行排序并找到第一个差异的索引(从左侧开始)。这是您的返回值之一(在示例中为2)。现在在原始文件(索引3)中找到sorted[2](即6)的索引。将值插入原始数组中就可以了。

答案 2 :(得分:1)

查找第一个未排序元素的方法不能正确解决所有情况,例如,如果数字是300200,则第一个未排序的数字是3,并且如果您将0放到该位置,则取决于您移动0的方式得到了:

(0)30020 (0)30020 (0)30200 (0)30200

所有答案都是错误的,因为您要做的就是将3放在数字的末尾以得到

(000)2003