Review
Not bad, but there is room for a few improvements to avoid some possible problematic input arguments.
Style
Some points on your code.
- The names
nums
and k
could be better, maybe array
and rotateBy
- Try to avoid one use variables unless it makes the lines using them to long. Thus you can pop and unshift in one line
nums.unshift(nums.pop());
- Idiomatic javascript uses zero based loop counters rather than starting at 1. Thus the loop would be
for (let i = 0; i < k; i++) {
Complexity
Your complexity is \$O(n)\$ and storage \$O(1)\$ where \$n\$ is the number of rotations, the range \$n>0\$
However consider the next examples
rotate([1,2,3,4,5,6,7,8,9], 18); // Will rotate 18 times same as rotate 0
rotate([1,2,3,4,5,6,7,8,9], 8); // Will rotate 8 times same as rotate left 1
rotate([1], 8e9); // Will spend a lot of time not changing anything
Your function will do too much work if the rotations are outside the expected ranges, the rotation can be done in reverse in less steps, or rotating has no effect.
You can limit the complexity to \$O(k)\$ where \$0<k<=n/2\$
Rewrite
This is a slight improvement on your function to ensure you don't rotate more than needed.
function rotate(array, rotateBy) {
rotateBy %= array.length;
if (rotateBy < array.length - rotateBy) {
while (rotateBy--) { array.unshift(array.pop()) }
} else {
rotateBy = array.length - rotateBy;
while (rotateBy--) { array.push(array.shift()) }
}
return array;
}
Update
As vnp's answer points out the complexity of Array.unshift
and Array.shift
is not as simple as \$O(1)\$ and will depend on the array type. We can assume the best case for this problem, sparse array (effectively a hash table) and thus will grow/shrink down at \$O(1)\$
In that case the function above has a mean complexity of \$O(log(n))\$ of all possible values of \$k\$
Note that if the cost of grow/shrink operations is \$O(n)\$ (dense array) this will add \$n\$ operations for each \$k\$ making the above \$O(kn)\$ with \$0<=k<(n/2)\$ Expressed in terms of \$n\$ or \$k\$ only it remains \$O(log(n))\$ or \$O(k)\$
You could also use Array.splice
array.unshift(...array.splice(-rotateBy,rotateBy));
However under the hood the complexity would be a little greater \$O(2n)\$ (which is still \$O(n)\$) as splice steps over each item to remove and add to a new array. Then ...
steps over them again to unshift
each item to the array.
The storage would also increase as the spliced array is held in memory until the code has finished unshifting them making storage \$O(n)\$
If the array contained all the same values the rotation would have no effect thus all rotation could be done in O(1). However there is no way to know this without checking each item in turn.