【字符串】B054_LC_困于环中的机器人(模拟 / 取模控制方向)

一、Problem

在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。机器人可以接受下列三条指令之一:

“G”:直走 1 个单位
“L”:左转 90 度
“R”:右转 90 度
机器人按顺序执行指令 instructions,并一直重复它们。

只有在平面中存在环使得机器人永远无法离开时,返回 true。否则,返回 false。

输入:"GGLLGG"
输出:true
解释:
机器人从 (0,0) 移动到 (0,2),转 180 度,然后回到 (0,0)。
重复这些指令,机器人将保持在以原点为中心,2 为半径的环中进行移动。

提示:

1 <= instructions.length <= 100
instructions[i] 在 {‘G’, ‘L’, ‘R’} 中

二、Solution

方法一:模拟

一开始的错误思路:用 set 存储每个座标点的字符串,如果再次遇到那么证明有环,这是片面的,因为我们可能一直重复该指令,比如下面的这种情况:

"GL"
输出:false
预期:true

讨论一下什么情况会回到起点;

  • 第一:从 (0, 0) -> (x, x) -> ... -> (0, 0),这个很好想
  • 第二:排除第一种情况后(注是排除),执行完一遍指令 instructions 后,只要方向与初始方向不同,那么执行 n 次指令机器人也不可能回到原点,因为它的运动范围只会不断地向外扩张
class Solution {
	final static int U = 0, D = 1, L = 2, R = 3;
    public boolean isRobotBounded(String instructions) {
    	char s[] = instructions.toCharArray();
    	int x = 0, y = 0,  d = U;

    	for (char c : s) {
    		if (c == 'G') {
    			switch (d) {
    				case U: x--; break;
    				case D: x++; break;
    				case L: y--; break;
    				case R: y++; break;
    			}
    		} else if (c == 'L') {
                switch (d) {
                    case U: d = L; break;
                    case D: d = R; break;
                    case L: d = D; break;
                    case R: d = U; break;
                }
    		} else {	// else if (c == 'R')
                switch (d) {
                    case U: d = R; break;
                    case D: d = L; break;
                    case L: d = U; break;
                    case R: d = D; break;
                }
    		}
    	}
    	return (x == 0 && y == 0) || d != U;
    }	
}

这个代码比较冗余,方向之间的转移可以通过数字变化来进行转移,比如 1>2, 2->3, 3->4, 4->1,而 4->1 可以通过取模来实现

:方向数组内部的一维数组的顺序是根据你的取模逻辑取定义的,如果当前方向是向北(k = 0),那么遇到向左转,此时你的方向数组的 k+1 位置应该是向西 (0, -1)

class Solution {
	final static int[][] dir = { {1,0},{0,-1},{-1,0},{0,1} };   //北、西、
    public boolean isRobotBounded(String instructions) {
    	char s[] = instructions.toCharArray();
        int x = 0, y = 0, k = 0;

    	for (char c : s) {
    		if (c == 'L') {
    			k = (k + 1) % 4;
    		} else if (c == 'R'){	
    			k = (k + 3) % 4;
    		} else {
    			x += dir[k][0];
    			y += dir[k][1];
    		} 
    	}
    	return (x == 0 && y == 0) || k != 0;
    }	
}

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章