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%的用户
一点感想
与题目没什么大关系,因为这道题是翻到了19年去头条面试的时候,在面试的桌子上,看到了上一位面试者留下的面试题目,当时应该是回去再LeetCode上找到了这道题目,看到了提交记录,使用的是翻转的方法完成的。
但是根据我的能力和习惯,当时一定是看了官方题解才做出来的,更有可能的是是把答案抄上去的。
其实面试过这么多次,没有真的专门准备过,都是一堆面试失败后,然后总结一下,然后可能发挥的不错一次拿到offer,像小米那次,也有可能是运气不错,找到了一个技术比较水的地方,比如现在
但是一般情况,那一堆失败的面试中,就有我真的想去的公司,结果这些公司成了练手
不想再这样,说不准什么时候又会到市场上被挑选,所以还是需要不断的联系,尤其是算法方面。到现在练习还是只能在简单的题目里面兜兜转转,好像没什么进步。
总会怀疑自己,这样的真的有用吗?是不是不要努力算了,都已经这么大了,没什么潜力的了吧?努力了这么久,好像也没什么长进。恰好昨天在知乎上看到了一篇文章,深以为然,里面说到
我们生活中遇到的所有事情基本可以分为三类:
第一类,纯粹由随机性决定,比如布朗运动和轮盘赌博;
第二类,纯粹由能力决定,比如英语六级考试,110米栏之类;
第三类,也是我们最常遇到的,由能力和随机性共同决定,比如创业,投资,恋爱或是梦想。
我们追求的、梦想的,运气绝对是扮演了决定性的因素,运气是一个绝对随机的事件,这个随机事件也许永远不会青睐你,那我们还要追求梦想吗?
这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。
我需要的,不是把感动自己的痛苦当做努力,而是默默地去付出真正的时间和经历,潜移默化的提升自己。突然想到为什么中学时期,为什么我能踢球、玩游戏的同时,学习成绩还很好,因为我当时很少做感动自己的无用功,像半夜看书学习,其实脑子已经不转了,都只是在在上课、该努力的时候心无旁骛的去用功,没有想过自己是不是很努力,因为没有觉得很辛苦,只是觉得在该做一件事的时候,就去做一件事,不去想自己做了这一道题,是不是下次考试就该增加5分
虽然运气是一个绝对随机性的事件(其实生活都是一个完全随机的事件,我们以为我们能够自主的做出决定,其实99%的时候,我们的决定都是被生活的随机事件所有左右,我们并没有真正的自我选择权利),但是努力绝对不是意见无所谓的事情:
恰恰相反,我一直相信,在能力没达到一定程度之前,你连面对随机性的资格都没有啊。
但生活的美妙之处却在于,很多事情在我们没做到一定程度之前,是完全没法理解的。
一个人能获得的最可贵的能力,都和掌握一门语言一样,你所付出的努力不是能够获得即时回馈的,甚至在很长的一段时间内没有任何收获,直到积累到了一定的阶段后,忽然爆发出惊人的力量,连你自己都不清楚这一切是如何发生的。
而最可贵的努力,是选择一个正确的方向,那些无法立即获得回报的事情,依然能付出十年如一日的专注和热情,最终的结果也许不足以让你独孤求败,但足以出类拔萃。
所谓厚积薄发
每一段岁月都有它存在的价值,没有高低贵贱之分,都不应该被辜负。
而我能想到的人这一生能做的最愚蠢的事情,就是把全部人生的希望都孤注一掷到未来的某个节点上,而忽略了生活本身应有的乐趣。
哪怕你以后真正实现了那个执念中的目标,才会发现它远远没你想的那么美好。
生命就在每天的生活里,一切执念都是虚妄,和身边的人愉快相处,认真安排好每一天的活动,用心去感受每一天的心境,就是生活的意义本身。
这碗鸡汤我干了。