尝试解决此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));
^有时它会给出带有正确交换索引的正确数字,有时数字和交换索引都错误。
答案 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