LeetCode054——螺旋矩阵

本文提供两种螺旋遍历矩阵的解决方案,一是使用visited数组记录访问状态,二是动态调整边界值,实现高效遍历。

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/spiral-matrix/description/

题目描述:

知识点:数组

思路一:用一个m行n列的数组visited记录该位置元素是否已被访问过

对于一个m行n列的数组matrix,我们要螺旋遍历之,我们需要螺旋多少圈呢?

我们可以通过找规律得出上述问题的答案。

mnturn
342
352
392
932
953

设min为m和n中的较小值,如果min能被2整除,那么我们需要螺旋min / 2圈。如果min不能被2整除,那么我们需要螺旋min / 2 + 1圈。

对于每一圈螺旋,我们都在上右下左4条边上依次遍历没有被访问过的位置,并将遍历到的没有被访问过的位置标记成已经被访问过。

时间复杂度和空间复杂度均是O(m * n)。

JAVA代码:

public class Solution {

	public List<Integer> spiralOrder(int[][] matrix) {
		List<Integer> list = new ArrayList<>();
		int m = matrix.length;
		if(m == 0) {
			return list;
		}
		int n = matrix[0].length;
		if(n == 0) {
			return list;
		}
		boolean[][] visited = new boolean[m][n];
		int turn = Math.min(m, n) % 2 == 0 ? Math.min(m, n) / 2 : Math.min(m, n) / 2 + 1;
		for (int k = 0; k < turn; k++) {	
			for (int i = 0; i < n; i++) {
				if(!visited[k][i]) {
					list.add(matrix[k][i]);
					visited[k][i] = true;
				}
			}
			for (int i = 0; i < m; i++) {
				if(!visited[i][n - 1 - k]) {
					list.add(matrix[i][n - 1 - k]);
					visited[i][n - 1 - k] = true;
				}
			}
			for (int i = n - 1; i >= 0; i--) {
				if(!visited[m - 1 - k][i]) {
					list.add(matrix[m - 1 - k][i]);
					visited[m - 1 - k][i] = true;
				}
			}
			for (int i = m - 1; i >= 0; i--) {
				if(!visited[i][k]) {
					list.add(matrix[i][k]);
					visited[i][k] = true;
				}
			}
		}
		return list;
	}
}

LeetCode解题报告:

思路二:实时更新螺旋的四个边界left、right、top、bottom的值

一开始,我们的四个边界分别如下:left = 0,right = n - 1,top = 0,bottom = m - 1。在while循环中,我们每遍历一条边就相应地改变某一边界的值,令其自增1或者自减1。

需要注意的是,在遍历下边界和左边界时,由于此时top值和right值均发现了改变,对于遍历下边界时,需要重新判断bottom是否大于等于top,对于遍历左边界时,需要重新判断right是否大于等于left。

时间复杂度是O(m * n)。空间复杂度是O(1)。

JAVA代码:

public class Solution {

	public List<Integer> spiralOrder(int[][] matrix) {
		List<Integer> list = new ArrayList<>();
		int m = matrix.length;
		if(m == 0) {
			return list;
		}
		int n = matrix[0].length;
		if(n == 0) {
			return list;
		}
		int top = 0;
		int bottom = m - 1;
		int left = 0;
		int right = n - 1;
		while(top <= bottom && left <= right) {
			for (int i = left; i <= right; i++) {
				list.add(matrix[top][i]);
			}
			top++;
			for (int i = top; i <= bottom; i++) {
				list.add(matrix[i][right]);
			}
			right--;
			if(bottom >= top) {
				for (int i = right; i >= left; i--) {
					list.add(matrix[bottom][i]);
				}
				bottom--;
			}
			if(right >= left) {
				for (int i = bottom; i >= top; i--) {
					list.add(matrix[i][left]);
				}
				left++;
			}
		}
		return list;
	}
}

LeetCode解题报告:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值