模拟行走机器人之略有技巧的贪心算法

机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令:
-2:向左转 90 度
-1:向右转 90 度
1 <= x <= 9:向前移动 x 个单位长度
在网格上有一些格子被视为障碍物。
第 i 个障碍物位于网格点 (obstacles[i][0], obstacles[i][1])
机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,但仍然可以继续该路线的其余部分。
返回从原点到机器人所有经过的路径点(坐标为整数)的最大欧式距离的平方。

例子:
输入: commands = [4,-1,3], obstacles = []
输出: 25
解释: 机器人将会到达 (3, 4)

补充:
1.二维空间的欧式距离指x2+y2
2.题目的最大欧式距离并不是指最终位置的欧式距离,而是整个过程中的
3.本题的贪心策略是,每走一段距离后,只要欧式距离更大就选择它,否则不变,mx=max(mx,x2+y2)。而本题难点并不在他,而是在如何控制方向,和前进。

思路:

  1. 方向:dx=[0,1,0,-1],dy=[1,0,-1,0],每个索引代表坐标轴四个方向,每个索引下的值代表该方向下每走一步,x或y增加的值,用d代表索引,初始d=0.那么dx[d]=0,dy[d]=1,即为面向北方。
  2. 控制方向:当命令=-2时,d=(d-1)%4;命令=-1时,d=(d+1)%4,方向改变。这里运用了python列表特殊索引(索引下标-1为最后元素,反向索引)
  3. 障碍物:预先判断是否下一步是否为障碍物坐标,是则直接退出本次命令
    注意:障碍物坐标要改用set()集合表示,这样查找是节省时间,否者用list()列表查找慢10000倍,并且超时
class Solution:
    def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
        mx=0
        dx=[0,1,0,-1]
        dy=[1,0,-1,0]
        d,x,y=0,0,0
        mp=set(map(tuple,obstacles))
        for i in commands:
            if i==-2:
                d=(d-1)%4
            if i==-1:
                d=(d+1)%4
            for j in range(i):
                if (x+dx[d],y+dy[d]) in mp:
                    break
                x+=dx[d]
                y+=dy[d]
            #欧距=x**2+y**2,每次命令仅对x和y中一个加减,最大值必在走完整段距离之后,所以每一次命令后贪心选择,而非每一步,节时。
            mx=max(mx,x**2+y**2)
        return mx

你可能感兴趣的:(贪心算法,贪心算法)