874. 模擬行走機(jī)器人(Python)

題目

難度:★★☆☆☆
類型:幾何枢贿、二維數(shù)組

機(jī)器人在一個(gè)無(wú)限大小的網(wǎng)格上行走俺猿,從點(diǎn) (0, 0) 處開始出發(fā)乔煞,面向北方褂傀。該機(jī)器人可以接收以下三種類型的命令:

-2:向左轉(zhuǎn) 90 度
-1:向右轉(zhuǎn) 90 度
1 <= x <= 9:向前移動(dòng) x 個(gè)單位長(zhǎng)度
在網(wǎng)格上有一些格子被視為障礙物啸罢。

第 i 個(gè)障礙物位于網(wǎng)格點(diǎn) (obstacles[i][0], obstacles[i][1])

如果機(jī)器人試圖走到障礙物上方编检,那么它將停留在障礙物的前一個(gè)網(wǎng)格方塊上,但仍然可以繼續(xù)該路線的其余部分扰才。

返回從原點(diǎn)到機(jī)器人的最大歐式距離的平方允懂。

提示
0 <= commands.length <= 10000
0 <= obstacles.length <= 10000
-30000 <= obstacle[i][0] <= 30000
-30000 <= obstacle[i][1] <= 30000
答案保證小于 2 ^ 31

示例

示例 1
輸入: commands = [4,-1,3], obstacles = []
輸出: 25
解釋: 機(jī)器人將會(huì)到達(dá) (3, 4)

示例 2
輸入: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
輸出: 65
解釋: 機(jī)器人在左轉(zhuǎn)走到 (1, 8) 之前將被困在 (1, 4) 處

解答

步長(zhǎng)問題。因?yàn)樯婕暗秸系K物的判斷衩匣,我們最好每次只走一步蕾总,而不是整條線路,邊走邊判斷前方是否有障礙物琅捏,模擬真實(shí)情況生百。

方向問題。機(jī)器人有四個(gè)方向可以行走柄延,且初始方向是北蚀浆,對(duì)每一個(gè)方向,向前走一步后的坐標(biāo)計(jì)算方式都是不同的,我們定義了方向列表市俊,表達(dá)向北杨凑、東、南摆昧、西(順時(shí)針)四個(gè)方向走一步后撩满,機(jī)器人的坐標(biāo)同上一步的區(qū)別, 定義dx = [0, 1, 0, -1] 绅你,dy = [1, 0, -1, 0]伺帘,使用di進(jìn)行方向索引(初始值為零,對(duì)應(yīng)于北方向)忌锯。例如曼追,向北走一步,對(duì)應(yīng)位移(0汉规, 1),相當(dāng)于x軸方向上+0驹吮,y軸方向上+1针史,我們通過(guò)di除以4取余的方式來(lái)確定左轉(zhuǎn)或右轉(zhuǎn)后的方向,以確保di索引在0到3之間碟狞。

障礙物啄枕。我們需要將障礙物設(shè)置成集合形式,這樣可以加速程序運(yùn)行族沃,方便進(jìn)行快速查找频祝。

循環(huán)。遍歷每一個(gè)控制量脆淹,對(duì)于左轉(zhuǎn)和右轉(zhuǎn)分別處理常空,對(duì)于前進(jìn)需要一步一步進(jìn)行,同步判斷前方是否有障礙物盖溺,如果有漓糙,則繼續(xù)執(zhí)行下一個(gè)控制指令,否則繼續(xù)前進(jìn)下去烘嘱。

class Solution:
    def robotSim(self, commands, obstacles):
        """
        :param commands: List[int]
        :param obstacles: List[List[int]]
        :return: int
        """

        dx = [0, 1, 0, -1]              # 北昆禽、東、南蝇庭、西
        dy = [1, 0, -1, 0]
        x = y = di = 0
        obstacles = set(map(tuple, obstacles))
        ans = 0

        for cmd in commands:
            if cmd == -2:               # 左轉(zhuǎn)
                di = (di - 1) % 4
            elif cmd == -1:             # 右轉(zhuǎn)
                di = (di + 1) % 4
            else:
                for k in range(cmd):
                    if (x + dx[di], y + dy[di]) not in obstacles:
                        x += dx[di]
                        y += dy[di]
                        ans = max(ans, x * x + y * y)
        return ans

面向?qū)ο笫蔷幊痰睦硐虢Y(jié)構(gòu)醉鳖,我們把機(jī)器人封裝成一個(gè)類,機(jī)器人類具有:

三個(gè)實(shí)例變量:可能的方向列表哮内,當(dāng)前方向索引(id盗棵,0到3),當(dāng)前位置(location);
兩個(gè)屬性:獲得當(dāng)前方向(direction)漾根,獲得當(dāng)前位置距離原點(diǎn)的平方和(dist_square)泰涂;
三個(gè)方法:左轉(zhuǎn)(turn_left),右轉(zhuǎn)(turn_right)辐怕,向前走一步(one_step)

向前走一步方法有一個(gè)輸入?yún)?shù)(have_a_try)逼蒙,如果設(shè)置為True,則不會(huì)修改機(jī)器人的當(dāng)前位置寄疏,否則會(huì)修改是牢,默認(rèn)為False。

我們用構(gòu)建的機(jī)器人類重構(gòu)上述代碼陕截,可以獲得更加簡(jiǎn)潔清晰易懂的表達(dá)效果驳棱,但是在這道題上執(zhí)行速度略有下降。這種面向?qū)ο蟮乃枷胫档脤W(xué)習(xí)农曲。

class Robot:

    def __init__(self):
        self.directions = ['north', 'east', 'south', 'west']
        self.id = 0
        self.location = (0, 0)

    def turn_left(self):
        self.id = (self.id - 1) % 4

    def turn_right(self):
        self.id = (self.id + 1) % 4

    @property
    def direction(self):
        return self.directions[self.id]

    @property
    def dist_square(self):
        return sum(map(lambda x: x*x, self.location))

    def one_step(self, have_a_try=False):          # 向一個(gè)方向移動(dòng)一步
        loc = self.location
        if self.direction == 'north':
            loc = self.location[0], self.location[1] + 1
        elif self.direction == 'east':
            loc = self.location[0] + 1, self.location[1]
        elif self.direction == 'south':
            loc = self.location[0], self.location[1] - 1
        elif self.direction == 'west':
            loc = self.location[0] - 1, self.location[1]
        if not have_a_try:
            self.location = loc
        return loc


class Solution:
    def robotSim(self, commands, obstacles):
        """
        :param commands: List[int]
        :param obstacles: List[List[int]]
        :return: int
        """

        robot = Robot()
        obstacles = set(map(tuple, obstacles))
        ans = 0                                     # 結(jié)果

        for cmd in commands:
            if cmd == -2:                           # 左轉(zhuǎn)
                robot.turn_left()
            elif cmd == -1:                         # 右轉(zhuǎn)
                robot.turn_right()
            else:
                for k in range(cmd):
                    if robot.one_step(have_a_try=True) in obstacles:
                        continue
                    else:
                        robot.one_step()
                        ans = max(ans, robot.dist_square)
        return ans

如有疑問或建議社搅,歡迎評(píng)論區(qū)留言~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乳规,隨后出現(xiàn)的幾起案子形葬,更是在濱河造成了極大的恐慌,老刑警劉巖暮的,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笙以,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡冻辩,警方通過(guò)查閱死者的電腦和手機(jī)猖腕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恨闪,“玉大人倘感,你說(shuō)我怎么就攤上這事×莅” “怎么了侠仇?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)犁珠。 經(jīng)常有香客問我逻炊,道長(zhǎng),這世上最難降的妖魔是什么犁享? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任余素,我火速辦了婚禮,結(jié)果婚禮上炊昆,老公的妹妹穿的比我還像新娘桨吊。我一直安慰自己威根,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布视乐。 她就那樣靜靜地躺著洛搀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佑淀。 梳的紋絲不亂的頭發(fā)上留美,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音伸刃,去河邊找鬼谎砾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捧颅,可吹牛的內(nèi)容都是我干的景图。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碉哑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼挚币!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起扣典,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤忘晤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后激捏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凄吏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年远舅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痕钢。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡图柏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出任连,到底是詐尸還是另有隱情蚤吹,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布随抠,位于F島的核電站裁着,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拱她。R本人自食惡果不足惜二驰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秉沼。 院中可真熱鬧桶雀,春花似錦矿酵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至棘捣,卻和暖如春辜腺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柱锹。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工哪自, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人禁熏。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓壤巷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瞧毙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子胧华,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354