【问题标题】:why my console.log shows a different value than what my function is returning for the same value fore Rotating an Array?为什么我的 console.log 显示的值与我的函数在旋转数组之前返回的相同值不同?
【发布时间】:2021-10-04 02:05:41
【问题描述】:

嗨,这是我在这里的第一篇文章,我正在尝试从 leetcode 解决这个问题https://leetcode.com/problems/rotate-array/,我知道这不是最好的解决方案,但我仍然对我得到的结果感到困惑。这是问题: 给定一个数组,将数组向右旋转 k 步,其中 k 是非负数。

例子:

输入:nums = [1,2,3,4,5,6,7], k = 3 输出:[5,6,7,1,2,3,4]

这是我的答案

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
};

当我执行 console.log(x) 时,我看到了正确答案,但是当我返回 x 时,它显示错误答案输出:[1,2,3,4,5,6,7] enter image description here 我在这里错过了什么?

【问题讨论】:

  • 您在哪里(在您的代码中)执行“console.log(x)”?另外,你为什么使用 JSON.parse() 函数?
  • 在任务中,在 JSDoc 中它说 * @return {void} 不返回任何内容,而是在原地修改 nums。”,这是不言自明的。见In-place algorithm
  • 我同意@SebastianSimon 所说的。我想补充的一件事是:如果 nums.length = 1,000,000(是的,100 万)怎么办?然后您的代码以 nums.length * nums.length 运行。这是 UBER 低效的。考虑一些更有效的方法。
  • “我知道这不是最好的解决方案” — 为什么还要嵌套循环?此任务需要线性传递。见Rotate the elements in an array in JavaScript
  • @Owen 我在返回 x 之前正在编写 console.log(x),但现在我重新阅读了这个问题,@sebastian 是对的,我不应该返回任何东西,只需要返回更改“数字”。但是,即使我在最后一行做x=nums,而不是返回,我也没有得到正确的答案。我也做了 JSON.parse() ,以制作我的数组的深层副本

标签: javascript arrays data-structures


【解决方案1】:

至于 '我的 console.log 显示的值与我的函数返回的值不同',您的代码工作正常。返回的值和里面的值在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)

但正如你所说'这不是最好的解决方案'。你可以在互联网上找到一些好的算法来提高效率。如果您执行这些任务是为了学习 javascript 而不是深入研究算法,您可以使用一些数组方法重写此函数。看看这段代码:

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)

它使用Array.slice() 方法将数组分成两部分:左和右。然后重新返回它们是相反的顺序。如此简单的解决方案。

***编辑:*** 您在评论中提供的第二种算法运行良好。但它很慢,因为它使用循环。想象一下您对一组 1000 个用户数据执行此算法的情况。它会减慢性能。 您可以编辑我建议的函数来操作给定的数组,而不是返回一个新数组。它要快得多。我在 Node.js 中创建了一个速度测试环境。然后对实际的 400 个帖子数据列表进行了一些速度测试。结果表明,我建议的算法比带循环的算法快 3.624 倍。见这里:

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

结果:

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

【讨论】:

  • 如果这对您有帮助,请告诉我
  • @Sanna 我会鼓励尽可能多地学习算法(如果您还不了解它们),因为“任何人都可以学习编程”但不是每个人都可以设计算法。 (由于很多人缺乏奉献精神/渴望)。
  • @ABDULLOKHMUKHAMMADJONOB 感谢您回答我的问题。我发现我错过了问题的一个重要部分,即“@return {void} 不要返回任何东西,而是就地修改 nums”。所以我尝试修改 nums 数组而不是制作新副本。我有什么,你怎么看?: var rotate = function(nums, k) { let n=0 let l= nums.length k=k%l let temp = [] while(n
  • @ABDULLOKHMUKHAMMADJONOB 如果您将解决方案复制粘贴到leetcode.com/problems/rotate-array,您将得到“错误答案”,这就是我无法将其标记为已接受的原因
  • 我觉得你应该改一下标题。它没有阐明问题的要点
猜你喜欢
  • 2020-04-06
  • 1970-01-01
  • 2022-01-19
  • 2017-05-05
  • 2021-12-25
  • 2020-04-28
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
相关资源
最近更新 更多