首页 > 试题广场 >

螺旋矩阵

[编程题]螺旋矩阵
  • 热度指数:139185 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。

数据范围:,矩阵中任意元素都满足
要求:空间复杂度 ,时间复杂度
示例1

输入

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

输出

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

输入

[]

输出

[]
public ArrayList<Integer> spiralOrder (int[][] matrix) {
        // 顺时针返回一个矩阵
        ArrayList<Integer> ans=new ArrayList<>();
        if(matrix==null||matrix.length==0) return ans;//这里一定要判空,否则无法通过
        //设置矩阵的四个边界值,截至条件为:左右边界/上下边界重合
        //从左到右,上边界下移一行   判断上下边界是否重合
        //从上到下,右边界左移一行   判断左右边界是否重合
        //从右到左,下边界上移一行   判断上下边界是否重合
        //从下到上,左边界右移一行   判断左右边界是否重合
        //循环判断这四步,直至循环结束
        int left=0;//左边界
        int right=matrix[0].length-1;//右边界(有效边界)
        int up=0;//上边界
        int down=matrix.length-1;//下边界(有效边界)
        while(left<=right&&up<=down){
            for(int i=left;i<right+1;i++){
                ans.add(matrix[up][i]);
            }
            up++;
            if(up>down) break;
            for(int i=up;i<down+1;i++){
                ans.add(matrix[i][right]);
            }
            right--;
            if(right<left) break;
            for(int i=right;i>=left;i--){
                ans.add(matrix[down][i]);
            }
            down--;
            if(down<up) break;
            for(int i=down;i>=up;i--){
                ans.add(matrix[i][left]);
            }
            left++;
            if(left>right) break;
        }
        return ans;
    }

发表于 2023-07-30 10:51:40 回复(0)
好麻烦
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> result = new ArrayList<>();
        if (matrix == null || matrix.length == 0) {
            return result;
        }
        int i = 0, iDirect = 0;
        int j = 0, jDirect = 0;
        int circle = 0;
        result.add(matrix[0][0]);
        while (result.size() <= (matrix.length * matrix[0].length)) {
            int totalNum = getCircleNods(matrix.length, matrix[0].length, circle);
            int jRange = (matrix[i].length - (circle + 1));
            int iRange = (matrix.length - (circle + 1));

            int up = (totalNum + (matrix.length - 2 * circle));
            int right = (up + ((matrix[0].length - 2 * circle) - 2));
            int down = (right + (matrix.length - 2 * circle));
            int left = (down + ((matrix[0].length - 2 * circle) - 2));
            if (totalNum <= result.size() && result.size() < up) {
                iDirect = 0;
                jDirect = 1;
                i = i + iDirect;
                if (j < jRange) {
                    j = j + jDirect;
                }
                result.add(matrix[i][j]);
            } else if (up <= result.size() && result.size() <= right ) {
                iDirect = 1;
                jDirect = 0;
                if (i < iRange) {
                    i = i + iDirect;
                }
                j = j + jDirect;
                result.add(matrix[i][j]);
            } else if (right < result.size()  && result.size() < down) {
                iDirect = 0;
                jDirect = -1;
                i = i + iDirect;
                if (j >= (circle + 1)) {
                    j = j + jDirect;
                }
                result.add(matrix[i][j]);
            } else if (down <= result.size() && result.size() < left) {
                iDirect = -1;
                jDirect = 0;
                if (i >= (circle + 1)) {
                    i = i + iDirect;
                }
                j = j + jDirect;
                result.add(matrix[i][j]);
            }
            if (right < up || down < right || left < down) {
                break;
            }
            if (result.size() == left) {
                circle++;
            }
        }
        return result;
    }

    public static int getCircleNods(int m, int n, int circle) {
        int totalNum = 0;
        for (int idx = 0; idx < circle; idx++) {
            totalNum += 2 * (m - 2 * idx) + 2 * ((n - 2 * idx) - 2);
        }
        return totalNum;
    }
}


发表于 2023-05-05 15:32:50 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        if (matrix.length == 0) {
            return list;
        }

        int res = matrix.length * matrix[0].length;
        int x = 0;
        int y = 0;
        int minx = 0;
        int maxx = matrix[0].length - 1;
        int miny = 0;
        int maxy = matrix.length - 1;

        if (maxx == 0 || maxy == 0) {
            for (int i = 0; i <= maxy; i++) {
                for (int j = 0; j <= maxx; j++) {
                    list.add(matrix[i][j]);
                }
            }
            return list;
        }


        for (int i = 0; i < res; i++) {
            list.add(matrix[y][x]);
            if (x == minx && y == (miny + 1)) {

                minx ++;
                maxx --;
                miny ++;
                maxy --;
                x ++;
                continue;
            }

            if (x == minx &&  y == miny && x < maxx && y <= maxy) {
                x++;
            } else if (x < maxx && y < maxy && x > minx) {
                x++;
            } else if (x == maxx && y < maxy) {
                y++;
            } else if (x > minx && y == maxy && y > miny) {
                x--;
            } else if (x == minx && y <= maxy && y > miny) {
                y--;
            }


        }
        return list;

    }
}

发表于 2022-11-02 17:25:27 回复(0)
这至少是个中等难度题目吧,牛客标记的简单题,咱就是说绕来绕去绕晕了,容易出现bug。
也顾不上代码简洁了,就这么绕吧。
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if (matrix.length == 0) return res;
        int[][] posmat = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
        int[] pos = new int[] {1, 0};
        int count = 0;
        int i = 0, j = 0;
        while (count < matrix.length * matrix[0].length) {
            if (j < matrix.length && j >= 0 && i < matrix[0].length && i >= 0 &&
                    matrix[j][i] != -999) {
                res.add(matrix[j][i]);
                matrix[j][i] = -999;
                count++;
                i += pos[0];
                j += pos[1];
            } else {
                i -= pos[0];
                j -= pos[1];
                if (pos[0] == 1 && pos[1] == 0) pos = posmat[1];
                else if (pos[0] == 0 && pos[1] == 1) pos = posmat[2];
                else if (pos[0] == -1 && pos[1] == 0) pos = posmat[3];
                else  pos = posmat[0];
                i += pos[0];
                j += pos[1];
            }
        }
        return res;
    }

}


发表于 2022-10-05 12:54:12 回复(0)
import java.util.ArrayList;
public class Solution {
    int[][] log;
    int n;
    int m;
    ArrayList<Integer> res=new ArrayList<>();
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        if(matrix.length==0){
            return res;
        }
        n=matrix.length;
        m=matrix[0].length;
        log=new int[n][m];
        int len=n*m;
        int i=0,j=0;
        while(res.size()<len){
            
            //右走
            while(j<m&&log[i][j]!=1){
                log[i][j]=1;
                
                res.add(matrix[i][j]);
                j++;
            }
            j--;
            i++;
            //下走
            while(i<n&&log[i][j]!=1){
                log[i][j]=1;
                
                res.add(matrix[i][j]);
                i++;
            }
            i--;
            j--;
            //左走
            while(j>=0&&log[i][j]!=1){
                log[i][j]=1;
                
                res.add(matrix[i][j]);
                j--;
            }
            j++;
            i--;
            //上走
            while(i>=0&&log[i][j]!=1){
                log[i][j]=1;
                
                res.add(matrix[i][j]);
                i--;
            }
            i++;
            j++;
        }
        
        return res;
    }
    
    
   
}

发表于 2022-08-31 23:50:46 回复(1)
import java.util.ArrayList;
import java.util.*;

public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        int m=matrix.length;//row
        ArrayList<Integer> path=new ArrayList<Integer>();
        if(m==0){//空即没有行也没有列---即没有行
            return path;
        }
        int n=matrix[0].length;//col

        
        //最开始的转圈位置
        int start_x=0,start_y=0;
        
        //转几圈
        int loop=Math.min(m,n)/2;
        int temp=loop;//备份后面用
        //如果min是奇数---会出现中间有一列或中间有一行---mid是起始位置
        int mid=Math.min(m,n)/2;;
        //用来控制遍历的边界
        int offset=1;
        while(loop>0){
            int i,j;
            for(i=start_x,j=start_y;j<=n-offset-1;j++){
                path.add(matrix[i][j]);
            }
            for(;i<=m-offset-1;i++){
                path.add(matrix[i][j]);
            }
            for(;j>=start_y+1;j--){
                path.add(matrix[i][j]);
            }
            for(;i>=start_x+1;i--){
                path.add(matrix[i][j]);
            }
            start_x=start_x+1;
            start_y=start_y+1;
            loop--;
            offset++;
        }
        if(Math.min(m,n)%2==1){
            int a,b;
            if(m>=n){//行多列少---中间剩下列
                //从mid开始的列
                for(a=mid,b=mid;a<=mid+m-temp*2-1;a++){
                    path.add(matrix[a][b]);
                }
            }
            if(n>m){//列多行少---中间剩下行
                //从mid开始的行
                for(a=mid,b=mid;b<=mid+n-temp*2-1;b++){
                    path.add(matrix[a][b]);
                }
            }
        }
        return path;
    }
    
        
}

发表于 2022-08-26 12:58:37 回复(0)
轻轻的我来了
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if (matrix.length == 0) return res;

        int top = 0, left = 0, right = matrix[0].length - 1, down = matrix.length - 1;

        while (left <= right && top <= down) {
            for (int i = left; i <= right; i ++) res.add(matrix[top][i]);
            top ++;
            if (top > down) break;
            for (int i = top; i <= down; i ++) res.add(matrix[i][right]);
            right --;
            if (left > right) break;
            for (int i = right; i >= left; i --) res.add(matrix[down][i]);
            down --;
            if (top > down) break;
            for (int i = down; i >= top; i --) res.add(matrix[i][left]);
            left ++;
            if (left > right) break;
        }

        return res;
    }
}

发表于 2022-08-12 20:01:22 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if(matrix==null || matrix.length==0) return new ArrayList<Integer>();
        
        int m = matrix.length, n = matrix[0].length;
        int up = 0, down = m-1, left = 0, right = n-1;
        while(up < down && left < right){
            for (int i = left; i < right; i++) res.add(matrix[up][i]);
            for (int i = up; i < down; i++) res.add(matrix[i][right]);
            for (int i = right; i > left; i--) res.add(matrix[down][i]);
            for (int i = down; i > up ; i--) res.add(matrix[i][left]);
            up++;
            right--;
            down--;
            left++;
        }
        if(up==down) for (int i = left; i <= right; i++) res.add(matrix[up][i]);
        else if(left==right) for (int i = up; i <= down; i++) res.add(matrix[i][left]);
        return res;
    }
}

发表于 2022-08-08 16:03:20 回复(0)
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if(matrix.length<1){
            return res;
        }
        int s1 = 0 ,e1 = matrix.length-1 ,s2 =0 ,e2 = matrix[0].length-1;
        while(s1<=e1 && s2<=e2){
            for(int i=s2;i<=e2;i++){
                res.add(matrix[s1][i]);
            }
            s1++;
            for(int i=s1;i<=e1;i++){
                res.add(matrix[i][e2]);
            }
            e2--;
            if(s1<=e1 && s2<=e2){
                for(int i=e2;i>=s2;i--){
                    res.add(matrix[e1][i]);
                }
                e1--;
                for(int i=e1;i>=s1;i--){
                    res.add(matrix[i][s2]);
                }
                s2++;
            }
        }
        return res;
    }

发表于 2022-06-25 16:31:12 回复(0)
import java.util.ArrayList;
import java.util.*;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        //如果数据组的长度为0,则直接返回空数组
        if(matrix.length == 0) return list;
        //定义四个方向的指针
        int top = 0,bottom = matrix.length - 1;
        int left = 0,right = matrix[0].length - 1;
        //当
        while( top < (matrix.length + 1)/2 && left < (matrix[0].length + 1)/2){
            //从左到右
            for(int i = left; i <= right; i++){
                list.add(matrix[top][i]);
            }
            //从上到下
            for(int i = top + 1; i <= bottom; i++){
                list.add(matrix[i][right]);
            }
            //从有到左
            for(int i = right - 1; top != bottom && i >= left; i--){
                list.add(matrix[bottom][i]);
            }
            //从下到上
            for(int i = bottom - 1; left != right && i >= top +1; i--){
                list.add(matrix[i][left]);
            }
            ++top;
            --bottom;
            ++left;
            --right;
        }
        return list;
    }
}

发表于 2022-05-29 16:12:15 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if(matrix == null || matrix.length == 0)
            return res;
        int m = matrix.length, n = matrix[0].length;
        int minIdx = Math.min(m, n);
        int loop = minIdx / 2; // 模拟次数
        int startx = 0, starty = 0;
        int offset = 1; // 控制边界的偏移量
        int i, j;
        // 参考代码随想录:区间[起点,终点),左闭右开
        while(0 < loop--){
            // 新的起点
            i = starty;
            j = startx;
            // 模拟上
            for(; j < startx + n - offset; j++)
                res.add(matrix[i][j]);
            //模拟右
            for(; i < starty + m - offset; i++)
                res.add(matrix[i][j]);
            // 模拟下
            for(; j > startx; j--)
                res.add(matrix[i][j]);
            // 模拟左
            for(; i > starty; i--)
                res.add(matrix[i][j]);
            startx++;
            starty++;
            offset += 2; //因为startx和starty也加了1,所以计算边界时需要将加的1减掉
        }
        if(minIdx % 2 == 1){ // 每次走2行2列,所以奇数行或奇数列最后会剩下一行或一列
            // while循环终止导致i和j没有更新
            i = starty;
            j = startx;
            if(m <= n){
                //模拟剩下的一行
                while(j <= startx + n - offset){
                    res.add(matrix[i][j]);
                    j++;
                }
            } else {
                // 模拟剩下的一列
                while(i <= starty + m - offset){
                    res.add(matrix[i][j]);
                    i++;
                }
            }
        }
        return res;
    }
}
发表于 2022-05-15 15:16:37 回复(0)
//类似于蛇形矩阵问题
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        int n = matrix.length;
        if(n == 0) return list;
        int m = matrix[0].length;
        
        int[] dx = {0,1,0,-1};
        int[] dy = {1,0,-1,0};
        boolean[][] st = new boolean[n][m];
        
        int d = 0;//表示刚开始是向右的方向
        int i = 0;
        int j = 0;//初始出发时的坐标
        for(int k = 0;k<n * m;k++){
            //先朝着一个方向一直走,走到头再换方向
            list.add(matrix[i][j]);
            st[i][j] = true;
            //尝试朝当前方向走一步
            int x = i + dx[d];
            int y = j + dy[d];
            if(x >= 0 && x < n && y >= 0 && y < m && !st[x][y]){
                i = x;
                j = y;//如果可以继续走那就继续走,不用换方向
            }else{
                d = (d + 1) % 4;//走不了时换方向
                i = i + dx[d];
                j = j + dy[d];
            }
        }
        return list;
    }
}

发表于 2022-04-25 15:47:16 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        int[][] next = {{0,1},{1,0},{0,-1},{-1,0}};
        int i = 0;
        int j = 0;
        int direct = 0;
        ArrayList<Integer> list = new ArrayList<>();
    
        while(matrix.length != 0){
            list.add(matrix[i][j]);
            matrix[i][j] = -123;
            if(list.size() == matrix.length * matrix[0].length) break;
            if( i + next[direct][0] > matrix.length - 1 ||
                j + next[direct][1] > matrix[0].length - 1 ||
                j + next[direct][1] < 0 ||
                i + next[direct][0] < 0 ||
                matrix[i + next[direct][0]][j + next[direct][1]] == -123 ){
                direct = (direct + 1) % 4;
            }
            
            i += next[direct][0];
            j += next[direct][1];
            
        }
        return list;
        
    }
}

发表于 2022-04-04 13:44:40 回复(0)

解题思路:通过四个数(代表上下左右)来构建边界,再按照左->右;上->下;右->左;下->上的次序完成遍历;
注意:开始遍历前判断数组是为为空可提升效率

import java.util.*;

public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        //通过四个指针不断收缩来限制顺时针遍历的范围
        ArrayList<Integer> res = new ArrayList<>();
        if(matrix.length==0) return res;
        int hang = matrix.length;  //行数
        int lie = matrix[0].length;  //列数
        int top=0,left=0,bot=hang-1,right=lie-1;  //上左下右四个边界
        int i=0,j=0;  //元素 matrix[i][j]
        int index=0;  //index记录矩阵中元素的个数
        while(index < hang*lie){
            //向列表中添加数据
            res.add(matrix[i][j]);
            //边界变更时,上下边界、左右边界不能重合,
            //所以添加判断 top+1<bot; left+1<right;
            if(i==top&&j<right){  //从左往右遍历
                j++;
                if(j==right&&top+1<bot){  //修改上边界
                    top++;
                }
            }else if(j==right&&i<bot){  //从上往下遍历
                i++;
                if(i==bot&&right-1>left){  //修改右边界
                    right--;
                }
            }else if(i==bot&&j>left){  //从右往左遍历
                j--;
                if(j==left&&bot-1>top){  //修改下边界
                    bot--;
                }
            }else if(j==left&&i>top){  //从下往上遍历
                i--;
                if(i==top&&left+1<right){  //修改左边界
                    left++;
                }
            }
            index++;
        }
        return res;
    }
}
发表于 2022-03-02 17:51:57 回复(0)
// 这题很容易写错,四个指针不断收缩
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if (matrix.length == 0) return res;
        int top = 0, left = 0, 
        right = matrix[0].length-1, bot = matrix.length-1;
        while (left <= right && top <= bot) {
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
            }
            for (int i = top+1; i <= bot; i++) {
                res.add(matrix[i][right]);
            }
            if (top < bot && left < right) {
                for (int i = right-1; i >= left; i--) {
                    res.add(matrix[bot][i]);
                }
                for (int i = bot-1; i >= top+1; i--) {
                    res.add(matrix[i][left]);
                }
            }
            left++;
            right--;
            top++;
            bot--;
        }
        return res;
    }
}

发表于 2022-02-02 16:19:41 回复(0)
这题居然是入门,真麻烦,搞四面墙,限制一下位置
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        if (matrix.length == 0) return list;
        int result = 0;
        if (matrix.length >= matrix[0].length){
            result = matrix[0].length;
        }else {
            result = matrix.length;
        }
        for (int i = 0; i < (result+1) / 2; i++) {
            test(matrix, i, i, matrix.length - i - 1, matrix[0].length - i - 1, list);
        }
        return list;
    }
    public void test(int[][] matrix,int m, int n, int l, int r,ArrayList<Integer> list){
        for (int i = n; i <= r; i++) {
            list.add(matrix[m][i]);
        }
        m++;
        for (int i = m; i <= l; i++) {
            list.add(matrix[i][r]);
        }
        r--;
        for (int i = r; i >= n && l >= m; i--) {
            list.add(matrix[l][i]);
        }
        l--;
        for (int i = l; i >= m && r >= n; i--) {
            list.add(matrix[i][n]);
        }
        n++;
    }
}


发表于 2022-01-25 00:24:12 回复(0)

问题信息

难度:
54条回答 24304浏览

热门推荐

通过挑战的用户