6 月更文挑战-兰顿蚂蚁

181 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

一、题目描述:

一只蚂蚁坐在由白色和黑色方格构成的无限网格上。开始时,网格全白,蚂蚁面向右侧。每行走一步,蚂蚁执行以下操作。

(1) 如果在白色方格上,则翻转方格的颜色,向右(顺时针)转 90 度,并向前移动一个单位。 (2) 如果在黑色方格上,则翻转方格的颜色,向左(逆时针方向)转 90 度,并向前移动一个单位。

编写程序来模拟蚂蚁执行的前 K 个动作,并返回最终的网格。

网格由数组表示,每个元素是一个字符串,代表网格中的一行,黑色方格由 'X' 表示,白色方格由 '_' 表示,蚂蚁所在的位置由 'L', 'U', 'R', 'D' 表示,分别表示蚂蚁 左、上、右、下 的朝向。只需要返回能够包含蚂蚁走过的所有方格的最小矩形。

示例 1:

输入: 0 输出: ["R"] 示例 2:

输入: 2 输出: [ "_X", "LX" ] 示例 3:

输入: 5 输出: [ "U", "X", "XX" ] 说明:

K <= 100000

来源:力扣(LeetCode) 链接:leetcode.cn/problems/la… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

将蚂蚁和网格实例化,可以更容易理解代码的逻辑.

蚂蚁对象主要包含左转,右转和前进等几个动作,以及当前所在位置和当前方向等属性;网格含获取某个位置处颜色,设置某个位置处颜色,翻转某个位置处颜色,更新网格边界等方法,以及蚂蚁足迹,网格边界以及获取结果等属性。

蚂蚁的下一步坐标可以由当前状态计算出,所以保存并时刻更新蚂蚁的状态,用集合保存块的位置,最后再通过集合生成字符串列表。

1.用“向量”记录方向,顺序与上一行方向的字符顺序保持一致,每个元素的后一个元素都是可以90°向右变换得到的

  1. 用集合存储所有黑块的坐标,一开始想再定义一个路径的坐标集合,发现可以直接用黑块+蚂蚁位置也能过
  2. 如果黑块集合能存入,说明脚下的块不在集合中,也就意味着是白色,方向序号循环自增1
  3. 否则说明脚下的块已经在集合中,也就意味着是黑色,方向序号循环自增3,相当于自减1,但是Math.floorMod取模可能消耗大?用+3替代

三、AC 代码:

class Solution {
    private class Position {
        
       
        int x, y;
        
        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
​
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + getEnclosingInstance().hashCode();
            result = prime * result + x;
            result = prime * result + y;
            return result;
        }
​
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Position other = (Position) obj;
            if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
                return false;
            if (x != other.x)
                return false;
            if (y != other.y)
                return false;
            return true;
        }
​
        private Solution getEnclosingInstance() {
            return Solution.this;
        }
​
    }
    
    public List<String> printKMoves(int K) {
        char[] direction = {'L', 'U', 'R', 'D'};
        int[][] offset = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
        Position antPos = new Position(0, 0);
         int antDir = 2;
        Set<Position> blackSet = new HashSet<>();
        while (K > 0) {
            Position t = new Position(antPos.x, antPos.y);
            if (blackSet.add(t)) {
                antDir = (antDir + 1) % 4;
            }else {
                 antDir = (antDir + 3) % 4;
                
                blackSet.remove(t);
            }
      
            antPos.x += offset[antDir][0];
            antPos.y += offset[antDir][1];
            K--;
        }
        int left = antPos.y, top = antPos.x, right = antPos.y, bottom = antPos.x;
        for (Position pos : blackSet) {
            left = pos.y < left ? pos.y : left;//y取小
            top = pos.x < top ? pos.x : top;//x取小
            right = pos.y > right ? pos.y : right;//y取大
            bottom = pos.x > bottom ? pos.x : bottom;//x取大
        }
        
        char[][] grid = new char[bottom - top + 1][right - left + 1];
       
        for (char[] row : grid)
            Arrays.fill(row, '_');
  
        for (Position pos : blackSet) {
             grid[pos.x - top][pos.y - left] = 'X';  
        }
           
       
        grid[antPos.x - top][antPos.y - left] = direction[antDir];
      
        List<String> result = new ArrayList<>();
        for (char[] row : grid)
            result.add(String.valueOf(row));
        return result;
    }
}

四、总结:

掘友们,解题不易,留下个赞或评论再走吧!谢啦~ 💐

希望对你有帮助,期待您找到心意的工作和满意的offer

期待下次再见~

\