[英]Find The Smallest - Codewars Challenge - Javascript
试图解决这个Codewars 挑战。
您有一个由数字组成的正数 n。 您最多可以执行一个操作:选择数字中某个数字的索引,在该索引处删除该数字并将其插入到另一个或数字中的同一位置,以便找到您可以获得的最小数字。
任务:根据语言返回数组或元组或字符串(请参阅“示例测试”):
1)你得到的最小数字
2)你取的数字d的索引i,i越小越好
3) 插入这个数字 d 以获得最小数字的索引 j(尽可能小)。
例子:
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));
^ 有时它给出正确的数字和正确的交换索引,有时数字和交换索引都是错误的。
将最小的元素放在前面(我们称之为“贪婪”的解决方案)是非最优的。 考虑n = 296837
的情况,如上一个测试用例。 您的代码返回[296837, 0, 0]
因为它发现2
是最小的数字并将其移到前面(基本上什么都不做)。 正如您的示例所示,有一种更好的方法: [239687, 4, 1]
,即将3
移动到数组中的第一个索引。
您需要重新制定策略以不贪婪地找到全局最优解。
如果您仍然卡住,您可以尝试以下操作:
数字不能包含那么多数字——为什么不尝试所有可能的交换?
这是一个可能会有所帮助的小想法。
如果你有一个类似的号码:
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)的索引。 将值插入原始数组中,就完成了。
找到第一个未排序元素的方法不能正确解决所有情况,例如如果数字是 300200,第一个未排序的数字是 3,如果你在那个地方放一个 0,取决于你移动的 0 你得到了什么:
(0)30020 (0)30020 (0)30200 (0)30200
所有的答案都是错误的,因为你要做的就是把 3 放在数字的末尾才能得到
(000)2003
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.