leetcode_54:Spiral Matrix

这个题目刚开始看其实感觉是有点麻烦的,就真的模仿了那种螺旋的思路走完一圈然后从某个地方再进去…。后来捋了一下思路,其实完全可以把它当做是一个一个的环。我们每次遍历都是在遍历一个环,然后再依次遍历下一个环。那么问题就变得简单了,只需要知道我们遍历一个环的时候需要哪些数据就行了。我们只需要两类数据:

  1. 一个环的左上角坐标
  2. 一个环的长度和宽度

有了这两类值,我们只需要不断地进行它们,就能不断地遍历一个个的环。

当然遍历环也比较简单,也就是从左上角开始不停地变化坐标就行。但是要注意的是,遍历环的时候如果遇到只有一行或者只有一列的情况,可能会添加重复的元素。虽然我写的时候感觉逻辑上一点问题没有(就是当做一个环来遍历),但是测试用例的第二个总是会多加一个6。当然那我知道是哪一行导致的,但是还是不太明白很通用的解决办法,所以只能是把这种只有一行或一列的环单独拿出来考虑。直接上代码:

    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> result = new LinkedList<>();
        if (matrix.length == 0)
            return result;
        int x = 0, y = 0, chang = matrix[0].length, kuan = matrix.length;
        while (chang > 0 && kuan > 0) {		//要保证环的长度和宽度大于0(有元素)
            List<Integer> temp = helper(matrix, x++, y++, chang, kuan);
            chang -= 2;		//没进入一个新环时,长、宽都要减去2
            kuan -= 2;
            result.addAll(temp);
        }
        return result;
    }

	//得到一个环的所有元素,参数为环左上角元素的坐标以及环的长度、宽度
    private List<Integer> helper(int[][] matrix, int x, int y, int chang, int kuan) {
        List<Integer> result = new LinkedList<>();
        int startX = x, startY = y;
        if (chang == 1) {   //只有一列
            for (; x < startX + kuan; ++x)
                result.add(matrix[x][y]);
            return result;
        } else if (kuan == 1) {     //只有一行
            for (; y < startY + chang; ++y)
                result.add(matrix[x][y]);
            return result;
        }
        for (; y < startY + chang; ++y)
            result.add(matrix[x][y]);
        --y;
        for (++x; x < startX + kuan; ++x)
            result.add(matrix[x][y]);
        --x;
        for (--y; y >= startY; --y)
            result.add(matrix[x][y]);
        ++y;
        for (--x; x > startX; --x)
            result.add(matrix[x][y]);
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值