[演算法][JavaScript]演算法挑战系列(5)-Spiral Matrix

HI啊,又到了一个礼拜一次的烧脑时间,其实这一次我真的很怕生不出来,所以我礼拜一就开始準备了,哈哈哈,今天的题目其实上礼拜就要Po了,可是那时候真的在电脑前面鬼打墙很久,就直接换到Hard难度的SQL题目了,所以这篇算是来还债的XD,感谢大家持续支持这个系列http://img2.58codes.com/2024/emoticon37.gif
这一次的题目有些人应该会很熟悉,其实就题目名称来说也算满常听到的,只是小的我第一次碰到,所以实作时苦恼很久http://img2.58codes.com/2024/emoticon70.gif,那还是一样废话不多说,直接来吧!
题目名称:Spiral Matrix
难易度:中
题目内容:传入一个二维阵列,依序由上、右、下、左,从外面往里面用螺旋的方式取值,回传该阵列中的所有元素。
例如:
1.传入以下阵列:
[
[1,2,3],
[4,5,6],
[7,8,9]
]
会回传阵列:[1,2,3,6,9,8,7,4,5]
2.传入以下阵列:
[
[1, 2, 3 ],
[4, 5, 6 ],
[7, 8, 9 ],
[10,11,12]
]
会回传阵列:[1,2,3,6,9,12,11,10,7,4,5,8]

好的,那以下是我苦思后的解法:

var spiralOrder = function(matrix) {        //如果传进来是空阵列就回传空阵列    if(matrix.length === 0){        return [];    }        //用来装解答    let ans = [];    //阵列中所有的数字有几个    let indexCount = matrix.length * matrix[0].length;    //用来记录目前的流程(0:上,1:右,2:下,3:左)    let seq = 0;    //指定回传的位置值    //第一维度是x,第二维度是y(等等进入迴圈后y会先+1所以初始值为-1)    let x = 0;    let y = -1;    //跑迴圈(如果解答阵列中的长度小于matrix的所有元素就继续跑,因为ans最后的阵列长度一定会和matrix一样)    while(ans.length < indexCount){        //指定位置        changeIndex(1);        //宣告一个变数用来放目前要抓的值        let nowValue;        //取值用try迴圈包起来        try{            //用目前指定的位置把值从阵列取出来            nowValue = matrix[x][y];        }        catch(err){            //如果超出该阵列範围就回传undefined            nowValue = undefined;        };        //如果回传的值不在ans里面又不是undefined就把他放进ans中        if(ans.indexOf(nowValue) ===- 1 && nowValue !== undefined){            ans.push(nowValue);        }        else{            /*这里是因为如果取出来undefuned或是重複的值,            要先把这一次迴圈加的位置减回来,            等于回复进入这一次迴圈前的状态。*/            changeIndex(-1);            //这里用来变动流程,依序由上:0,右:1,下:2,左:3去取值            if(seq === 3){                seq = 0;            }            else{                seq+=1;            }        };    };        //用来变动位置,index传入变动值    function changeIndex (index){        //确认目前流程,依照流程来做变动(如果传进-1就是回复之前的状态)        switch(seq){            case 0:{                //如果是0(上),就是往右一格,所以y+1                y+=index;                break;            };            case 1:{                //如果是1(右),就是往下一格,所以x+1                x+=index;                break;            };            case 2:{                //如果是2(下),就是往左一格,所以y-1                y-=index;                break;            };            case 3:{                //如果是3(左),就是往上一格,所以x-1                x-=index;                break;            };        };    };    //最后回传装完所有值的阵列    return ans;    };

接着我分享一下这一次的成绩,执行时间大概是56ms,然后赢过了77.16%的解答,其实一开始我送答案的时候才7%,一个吓到吃手手,立马修了第二版本出来XD,另外之前SQL之所以没有贴上执行成绩是因为送答案的人太少了,才让那个系统没办法产生图表,所以这一次分享一下!
http://img2.58codes.com/2024/20106935dZagEQqmcC.jpg
还有我在讨论区看到一个赢过95%答案的神之解答,完全用函式解决一堆逻辑上的问题,看完后真觉得自己对JS的熟练度还真的低到爆炸XD,那来看一下大神解法:
原解答网址

var spiralOrder = function (matrix) {    "use strict";    //宣告一个新阵列    var res = [];    //一个function来判断阵列内是否还有值,如果有就回传false,没有就true    var isEmpty = function isEmpty() {        return matrix.length === 0 || matrix[0].length === 0;    };    //如果他还不是空的就继续跑迴圈    while (!isEmpty()) {        //抓出matrix的第一个阵列位置,并把他放进res中(处理上面的部分)        res = res.concat(matrix.shift());         //确认目标阵列是否为空,如果是空的就跳出        if (isEmpty()) break;        //去跑迴圈,经过目前的所有位置        for (var i = 0; i < matrix.length; i++) {            //把每个位置的最后一个值抓出来放进res中(处理右边的部分)            res.push(matrix[i].pop());         }                //确认目标阵列是否为空,如果是空的就跳出        if (isEmpty()) break;        //把最后一个位置抓出来,反转后放进res中(处理下面的部份)        res = res.concat(matrix.pop().reverse());        //确认目标阵列是否为空,如果是空的就跳出        if (isEmpty()) break;        //去跑迴圈,经过目前的所有位置        for (var _i = matrix.length - 1; _i >= 0; _i--) {            //把每个位置的第一个值抓出来放进res中(处理左边的部分)            res.push(matrix[_i].shift());        }    }    //重複以上流程,直到目标阵列被处理到空了为止。    return res;};

上面的程式码可能会和原文解答有点不同,因为我把它从ES6转到ES5的语法,也照惯例的加了一堆注解,不然我真的还不太熟ES6http://img2.58codes.com/2024/emoticon06.gif
那以上是这礼拜的分享,虽然总算回到熟悉的JavaScript但也同时觉得世界还很大,有更多要学习的地方,算是一个收穫满满的一个礼拜XD。那一样欢迎各位大大一起来讨论各自的解法,如果以上文章中有不小心手误、或是有问题的地方还请大家告诉我,我会立即改进!这一週依然感谢大家!没有你们我一定坚持不到现在!http://img2.58codes.com/2024/emoticon41.gif


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章