0

hi there this is my first post here, I'm trying to solve this question https://leetcode.com/problems/rotate-array/ from leetcode, I know it's not the best solution but still, I'm confused by the outcome I get. this is the question: Given an array, rotate the array to the right by k steps, where k is non-negative.

Example :

Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4]

and here is my answer

var rotate = function(nums, k) {
    
    let n=0
    let temp = []
    let l =nums.length
    k=k%l
    let x = JSON.parse(JSON.stringify(nums))
    while(n<k){
        let last = x[l-1]
        for(let i=1;i<l;i++){
            temp[i] = x[i-1]
        }
        temp[0]=last
        x=JSON.parse(JSON.stringify(temp))
        n++
    }
    
    return x
};

when I do console.log(x) I see the correct answer but when I'm returning x, it says wrong answer Output:[1,2,3,4,5,6,7] enter image description here what am I missing here?

Sanna
  • 11
  • Where (in your code) are you doing "console.log(x)"? In addition, why are you using JSON.parse() function? – Owen Murphy Oct 04 '21 at 02:12
  • In the task, in the JSDoc it says _“`* @return {void}` Do not return anything, modify nums in-place instead.”_, which is pretty self-explanatory. See [In-place algorithm](//en.wikipedia.org/wiki/In-place_algorithm). – Sebastian Simon Oct 04 '21 at 02:17
  • I agree with that @SebastianSimon said. One thing I would like to add is the following: What if nums.length = 1,000,000 (yes, 1 million)? Then your code runs in nums.length * nums.length. Which is UBER inefficient. Consider something more efficient. – Owen Murphy Oct 04 '21 at 02:19
  • _“I know it's not the best solution”_ — Why do you even have a nested loop? This task requires a linear pass. See [Rotate the elements in an array in JavaScript](/q/1985260/4642212). – Sebastian Simon Oct 04 '21 at 02:26
  • @Owen i'm writing console.log(x) right before return x, but now that I re-read the question, @sebastian is right, I shouldn't return anything and only need to change 'nums'. but still, even when I'm doing `x=nums` at the very last line, instead of return I don't get the right answer. also I did JSON.parse() , to make a deep copy of my array – Sanna Oct 04 '21 at 02:50
  • @SebastianSimon thank you for the links, I'm really new to the whole data structure and I'm learning by myself. do you have more resources or idea of where is the best place to start learning data structures? – Sanna Oct 04 '21 at 03:05
  • @Sanna x = nums is the opposite of what you want. But nums = x won't work either because you were supposed to mutate the array that was already in nums, and overwriting your local argument variable won't have any effect. So you need an algorithm that works on the array itself. – CherryDT Oct 04 '21 at 12:25

1 Answers1

0

As for 'my console.log shows a different value than what my function is returning', your code is working correctly. The value returned and the value inside are same on console.log()

var rotate = function(nums, k) {
    let n=0
    let temp = []
    let l =nums.length
    k=k%l
    let x = JSON.parse(JSON.stringify(nums))
    while(n<k){
        let last = x[l-1]
        for(let i=1;i<l;i++){
            temp[i] = x[i-1]
        }
        temp[0]=last
        x=JSON.parse(JSON.stringify(temp))
        n++
    }
    console.log("before return: ", x)
    return x
};
const rotated = rotate([1,2,3,4,5,6,7], 3)
console.log(rotated)

But as you say 'it is not the best solution'. You can find some good algorithms on the internet to make it efficient. If you are doing these tasks to learn javascript rather than diving into algorithms, you can rewrite this function using some array methods. Check out this code:

const rotateAfter = (nums, k) => {
    const leftSide = nums.slice(0, k+1)
    const rightSide = nums.slice(k+1, nums.length)
    return rightSide.concat(leftSide)
}
const rotatedArray = rotateAfter([1,2,3,4,5,6,7], 3)
console.log(rotatedArray)

It splits the array into two parts: left and right using Array.slice() method. Then reurns them is inverse order. Such a simple solution.

***Edit: *** The second algorithm you provided in the comment is working fine. But it is slow as it uses a loop. Imagine the situation you perform this alogrithm on an array of 1000 users data. It slows down the performance. You can edit the function I suggested to manipulate the given array rather than returning a new one. It is much faster. I created a speed testing environment in Node.js. Then performed some speed tests on a list of actual 400 posts data. The results show that the algorithm I suggested was roughly 3.624 times faster than the one with a loop. See here:

const posts = [
  // ..... 400
  {
    "userId": 10,
    "id": 199,
    "title": "numquam repellendus a magnam",
    "completed": true
  },
  // .....
]

var algorithm1 = function(nums, k) { 
  const started = present()
  let n=0;
  let l= nums.length;
  k=k%l;
  let temp = [];
  while(n<k){ 
    temp.unshift(nums.pop());
    n++ 
  }
  nums.unshift(...temp)
  console.log("alg1 took: ", present()-started)
};


const algorithm2 = (nums, k) => {
    const started = present()
    const leftSide = nums.slice(k+1, nums.length)
    nums.splice(k+1, nums.length-1)
    nums.unshift(...leftSide)
    console.log("alg2 took: ", present()-started)
}

algorithm1(posts, 275)
algorithm2(posts, 275)
// note that it only works in node.js environment

Results:

alg1 took:  0.21170002222061157
alg2 took:  0.06599998474121094
running ...

alg1 took:  0.20789998769760132
alg2 took:  0.06470000743865967
running ...

alg1 took:  0.19339996576309204
alg2 took:  0.025599956512451172
running ...

alg1 took:  0.21679997444152832
alg2 took:  0.12199997901916504
running ...

alg1 took:  0.2791000008583069
alg2 took:  0.05779999494552612
running ...

alg1 took:  0.3149999976158142
alg2 took:  0.05210000276565552
running ...

alg1 took:  0.2116999626159668
alg2 took:  0.06309998035430908
ABDULLOKH MUKHAMMADJONOV
  • 4,249
  • 3
  • 22
  • 40
  • Let me know if this was helpful for you – ABDULLOKH MUKHAMMADJONOV Oct 04 '21 at 02:56
  • @Sanna I would encourage though to learn algorithms (if you don't already know them) as much as you can, seeing that "anyone can learn to program" but not everyone can design algorithms. (due to the lack dedication/desire in a lot of people). – Owen Murphy Oct 04 '21 at 03:16
  • @ABDULLOKHMUKHAMMADJONOB thank you for answering my question. I found out I've missed an important part of the question, which is "@return {void} Do not return anything, modify nums in-place instead." so I tried to modify the nums array instead of making a new copy. here what I have, what do you think?: var rotate = function(nums, k) { let n=0 let l= nums.length k=k%l let temp = [] while(n – Sanna Oct 04 '21 at 03:43
  • @ABDULLOKHMUKHAMMADJONOB if you copy paste your solution in https://leetcode.com/problems/rotate-array/ you'll get "wrong answer", that's why i can't mark it as accepted – Sanna Oct 04 '21 at 13:56
  • I think you should change the title then. It does not clarify main point of the question – ABDULLOKH MUKHAMMADJONOV Oct 04 '21 at 14:08