我在数组中练习了一些问题的编码: 这是我的问题: https://www.hackerrank.com/challenges/array-left-rotation/problem
这是我的解决方案:
function leftRotation(a, d) {
// Complete this function
var result = new Array(a.length);
for (i = 0; i < a.length; i++) {
var what = i - d;
if (what < 0) {
result[a.length + what] = a[i];
} else {
result[what] = a[i];
}
}
return result;
}
我的解决方案通过了所有测试用例,但我不知道为什么它是正确的。
详细说明,在此代码块中
if (what < 0) {
result[a.length + what] = a[i];
}
我通过检查实数来找到该公式,并且在很多情况下它是正确的,然后我实现了它。但我不知道它为什么是正确的,因为我从未见过索引数组长度之间的任何关系。如果你知道,请帮忙解释一下。
P / s:如果您有解决此问题的任何方法(我的意思是可解释的解决方案,而不是像我这样),请帮助将其发布在此处。
提前感谢一大堆!
答案 0 :(得分:1)
很难理解代码如何工作的一个很好的部分原因是命名不佳。我使用了与您提供的完全相同的逻辑/代码,但重命名的内容更加清晰。对于任何事情,what
都是一个特别糟糕的名称选择。
请注意,我为a.length
创建了一个变量,而不是调用它3次。我还使用了const
而不是var
,因为HackerRank支持Node.js. const
对于在声明后不会重新分配的变量很有用,例如在这种情况下。对于可以重新分配的变量,请使用let
代替const
或var
。
我在代码中包含了解释性注释。希望这可以帮助。
function leftRotation(inputArr, rotations) {
// calculate length once and reuse it
const inputArrLength = inputArr.length;
// we will put the values with their new indexes in this array
const rotatedArr = new Array(inputArrLength);
// iterate over index (idx) of each value in inputArr
for (idx = 0; idx < inputArrLength; idx++) {
// find out what the new index will be after rotating
const newIdx = idx - rotations;
// set index to the back of the array if it has to "wrap around"
if (newIdx < 0) {
// newIdx is negative so adding it actually subtracts it from length
rotatedArr[inputArrLength + newIdx] = inputArr[idx];
}
// otherwise just set the new index
else {
rotatedArr[newIdx] = inputArr[idx];
}
}
return rotatedArr;
}
在考虑这个问题的同时,我想出了一个更简单的算法,我认为它更直观(也可能更快)。这类似于人们如何将物体物理地滑动到左侧并将那些从表面/阵列上掉落的物体放在后面/右侧。它具有较少的算术运算,因为旋转偏移仅计算一次,然后用于划分索引。它还通过了所有测试用例。
function leftRotation(inputArr, rotations) {
const inputArrLength = inputArr.length;
const rotatedArr = new Array(inputArrLength);
const wrapAroundIdxOffset = inputArrLength - rotations;
// we can just "slide" to the left any values' idx that
// don't need to wrap around the beginning/left of array
for(idx = rotations; idx < inputArrLength; idx++) {
rotatedArr[idx - rotations] = inputArr[idx];
}
// and the others get wrapped around
for(idx = 0; idx < rotations; idx++) {
rotatedArr[wrapAroundIdxOffset + idx] = inputArr[idx];
}
return rotatedArr;
}
答案 1 :(得分:0)
在问题中提到 d&lt; = n
所以假设你想要将第0个索引旋转3个位置,假设数组的长度为n。
第一次旋转,现在元素在n-1,在第二次旋转之后它将在n-2,在第3次旋转之后它将在n-3。
所以我处于第0个索引并想要左旋3次,对于这种情况
what = -3;
因此
result[n-3] = a[0];
这正是我们想要的,现在第一和第二指数可以类似地旋转到 n-2 和 n-1 指数。
这就是为什么你的解决方案有效,因为d&lt; = n而我们只是想把它们放在什么位置
使用数组是
[1, 2, 3, 4, 5]
让我们将这个数组连接到自身,这样数组现在就是
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
现在左移2意味着我们需要从索引 2 到 7 的数组,即
[3, 4, 5, 1, 2]
现在你可以看到a [5] = a [0]或a [i + n] = a [i],在结果数组中我们将删除[0]和[1]所以现在< / p>
a [5]将成为[5-2]而[6]将成为[6-2]或[5-1]或 a [n +(id)]