48. 旋转图像(2021.06.04)

本文详细介绍了LeetCode第48题《旋转图像》的两种JavaScript解法,包括辅助数组和翻转矩阵。通过实例解析了矩阵旋转的逻辑,并探讨了编程思维和面试准备的重要性,强调了在编程学习中避免感动自己,要注重实际技能的积累和提高。
摘要由CSDN通过智能技术生成

48. 旋转图像

链接:https://leetcode-cn.com/problems/rotate-image/

题目描述见链接内容。

解法1:辅助数组

既然让原地修改数组,但是我又想不出来如何直接修改,就像之前做的一道题目一样,直接声明一个新的数组,把调换后的数组按顺序推入新的数组中就行了

然后需要找到替换的规律,脑子不够用,就用了3x3的矩阵,一个一个列,用归纳法,找到规律:

temp[j][length - i - 1] = matrix[i][j]; // i是行,j是列

然后把得到的temp遍历赋值给原来的matrix就行了

var rotate = function (matrix) {
  const temp = [];
  const length = matrix.length;

  for (let i = 0; i < length; i++) {
    if (!Array.isArray(temp[i])) {
      temp[i] = [];
    }

    for (let j = 0; j < length; j++) {
      if (!Array.isArray(temp[j])) {
        temp[j] = [
      }

      temp[j][length - i - 1] = matrix[i][j];
    }
  }

  for (let i = 0; i < length; i++) {
    for (let j = 0; j < length; j++) {
      matrix[i][j] = temp[i][j];
    }
  }
};
  • 时间复杂度:${O(N^2)}$N是输入的矩形矩阵的变长
  • 空间复杂度:${O(N^2)}$,需要一个和输入的矩阵一样大的辅助数组
  • 执行用时:80ms, 在所有JavaScript提交中击败了83%的用户,内存消耗:37.9MB,在所有JavaScript提交中击败了71%的用户

解法2:翻转

智商不够用的人,只会像我一样,用上面的死方法,智商在线的人对这种题目只会不屑一顾,顺手抛出了一个翻转代替旋转的方法,为什么要用翻转代替旋转,因为翻转的话,只是在两个数之间交换,不会涉及到第三者,这样就避免了旧值被覆盖的问题

那关键就是如何翻转,聪明的人一下就看出来,我就看不出,还是笨,实际上就是两步,第一步列对调,第二步沿对角线对调:

[
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

// 列对调
[
    [3, 2, 1],
    [6, 5, 4],
    [9, 8, 7]
]

// 沿对角线对调
[
    [7, 4, 1],
    [8, 5, 2],
    [9, 6, 3]
]

比较麻烦的是,沿对角线对调的规律,找了半天才找出来,还是用的归纳法,就是硬推

[matrix[i][j], matrix[length - 1 - j][length - 1 - i]] = [matrix[length - 1 - j][length - 1 - i], matrix[i][j]];

这样就完事了

var rotate = function (matrix) {
  const length = matrix.length;

  for (let i = 0; i < length; i++) {
    let start = 0,
      end = length - 1;

    while (start < end) {
      [matrix[i][start], matrix[i][end]] = [matrix[i][end], matrix[i][start]];
      start += 1;
      end -= 1;
    }
  }

  for (let i = 0; i < length - 1; i++) {
    for (let j = 0; j < length - 1 - i; j++) {
      [matrix[i][j], matrix[length - 1 - j][length - 1 - i]] = [matrix[length - 1 - j][length - 1 - i], matrix[i][j]];
    }
  }
};
  • 时间复杂度:${O(N^2)}$N是输入的矩形矩阵的变长,每一次翻转,都要枚举矩阵中一半的元素
  • 空间复杂度:${O(1)}$
  • 执行用时:88ms, 在所有JavaScript提交中击败了52%的用户,内存消耗:40.4MB,在所有JavaScript提交中击败了10.11%的用户

上面是线调换列,思考起来好别扭,完全可以先调换行,然后对角线调换,思考起来简单的多:

var rotate = function (matrix) {
  const len = matrix.length;

  // 行对调
  let start = 0,
    end = len - 1;
  while (start < end) {
    for (let i = 0; i < len; i++) {
      [matrix[start][i], matrix[end][i]] = [matrix[end][i], matrix[start][i]];
    }
    start += 1;
    end -= 1;
  }

  // 对角线对调
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
    }
  }
};
  • 时间复杂度:${O(N^2)}$N是输入的矩形矩阵的变长,每一次翻转,都要枚举矩阵中一半的元素
  • 空间复杂度:${O(1)}$
  • 执行用时:76ms, 在所有JavaScript提交中击败了92.34%的用户,内存消耗:40.2MB,在所有JavaScript提交中击败了15.37%的用户

一点感想

与题目没什么大关系,因为这道题是翻到了19年去头条面试的时候,在面试的桌子上,看到了上一位面试者留下的面试题目,当时应该是回去再LeetCode上找到了这道题目,看到了提交记录,使用的是翻转的方法完成的。

但是根据我的能力和习惯,当时一定是看了官方题解才做出来的,更有可能的是是把答案抄上去的。

其实面试过这么多次,没有真的专门准备过,都是一堆面试失败后,然后总结一下,然后可能发挥的不错一次拿到offer,像小米那次,也有可能是运气不错,找到了一个技术比较水的地方,比如现在

但是一般情况,那一堆失败的面试中,就有我真的想去的公司,结果这些公司成了练手

不想再这样,说不准什么时候又会到市场上被挑选,所以还是需要不断的联系,尤其是算法方面。到现在练习还是只能在简单的题目里面兜兜转转,好像没什么进步。

总会怀疑自己,这样的真的有用吗?是不是不要努力算了,都已经这么大了,没什么潜力的了吧?努力了这么久,好像也没什么长进。恰好昨天在知乎上看到了一篇文章,深以为然,里面说到

我们生活中遇到的所有事情基本可以分为三类:

第一类,纯粹由随机性决定,比如布朗运动和轮盘赌博;

第二类,纯粹由能力决定,比如英语六级考试,110米栏之类;

第三类,也是我们最常遇到的,由能力和随机性共同决定,比如创业,投资,恋爱或是梦想。

我们追求的、梦想的,运气绝对是扮演了决定性的因素,运气是一个绝对随机的事件,这个随机事件也许永远不会青睐你,那我们还要追求梦想吗?

这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。

我需要的,不是把感动自己的痛苦当做努力,而是默默地去付出真正的时间和经历,潜移默化的提升自己。突然想到为什么中学时期,为什么我能踢球、玩游戏的同时,学习成绩还很好,因为我当时很少做感动自己的无用功,像半夜看书学习,其实脑子已经不转了,都只是在在上课、该努力的时候心无旁骛的去用功,没有想过自己是不是很努力,因为没有觉得很辛苦,只是觉得在该做一件事的时候,就去做一件事,不去想自己做了这一道题,是不是下次考试就该增加5分

虽然运气是一个绝对随机性的事件(其实生活都是一个完全随机的事件,我们以为我们能够自主的做出决定,其实99%的时候,我们的决定都是被生活的随机事件所有左右,我们并没有真正的自我选择权利),但是努力绝对不是意见无所谓的事情:

恰恰相反,我一直相信,在能力没达到一定程度之前,你连面对随机性的资格都没有啊。

但生活的美妙之处却在于,很多事情在我们没做到一定程度之前,是完全没法理解的。

一个人能获得的最可贵的能力,都和掌握一门语言一样,你所付出的努力不是能够获得即时回馈的,甚至在很长的一段时间内没有任何收获,直到积累到了一定的阶段后,忽然爆发出惊人的力量,连你自己都不清楚这一切是如何发生的。

而最可贵的努力,是选择一个正确的方向,那些无法立即获得回报的事情,依然能付出十年如一日的专注和热情,最终的结果也许不足以让你独孤求败,但足以出类拔萃。

所谓厚积薄发

每一段岁月都有它存在的价值,没有高低贵贱之分,都不应该被辜负。

而我能想到的人这一生能做的最愚蠢的事情,就是把全部人生的希望都孤注一掷到未来的某个节点上,而忽略了生活本身应有的乐趣。

哪怕你以后真正实现了那个执念中的目标,才会发现它远远没你想的那么美好。

生命就在每天的生活里,一切执念都是虚妄,和身边的人愉快相处,认真安排好每一天的活动,用心去感受每一天的心境,就是生活的意义本身。

这碗鸡汤我干了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值