|
| 1 | +--- |
| 2 | +title: 2087.网格图中机器人回家的最小代价:脑筋急转弯(固定走法) |
| 3 | +date: 2026-04-04 14:43:15 |
| 4 | +tags: [题解, LeetCode, 中等, 贪心, 数组, 脑筋急转弯] |
| 5 | +categories: [题解, LeetCode] |
| 6 | +index_img: https://assets.leetcode.com/uploads/2021/10/11/eg-1.png |
| 7 | +--- |
| 8 | + |
| 9 | +# 【LetMeFly】2087.网格图中机器人回家的最小代价:脑筋急转弯(固定走法) |
| 10 | + |
| 11 | +力扣题目链接:[https://leetcode.cn/problems/minimum-cost-homecoming-of-a-robot-in-a-grid/](https://leetcode.cn/problems/minimum-cost-homecoming-of-a-robot-in-a-grid/) |
| 12 | + |
| 13 | +<p>给你一个 <code>m x n</code> 的网格图,其中 <code>(0, 0)</code> 是最左上角的格子,<code>(m - 1, n - 1)</code> 是最右下角的格子。给你一个整数数组 <code>startPos</code> ,<code>startPos = [start<sub>row</sub>, start<sub>col</sub>]</code> 表示 <strong>初始</strong> 有一个 <strong>机器人</strong> 在格子 <code>(start<sub>row</sub>, start<sub>col</sub>)</code> 处。同时给你一个整数数组 <code>homePos</code> ,<code>homePos = [home<sub>row</sub>, home<sub>col</sub>]</code> 表示机器人的 <strong>家</strong> 在格子 <code>(home<sub>row</sub>, home<sub>col</sub>)</code> 处。</p> |
| 14 | + |
| 15 | +<p>机器人需要回家。每一步它可以往四个方向移动:<strong>上</strong>,<strong>下</strong>,<strong>左</strong>,<strong>右</strong>,同时机器人不能移出边界。每一步移动都有一定代价。再给你两个下标从 <strong>0</strong> 开始的额整数数组:长度为 <code>m</code> 的数组 <code>rowCosts</code> 和长度为 <code>n</code> 的数组 <code>colCosts</code> 。</p> |
| 16 | + |
| 17 | +<ul> |
| 18 | + <li>如果机器人往 <strong>上</strong> 或者往 <strong>下</strong> 移动到第 <code>r</code> <strong>行</strong> 的格子,那么代价为 <code>rowCosts[r]</code> 。</li> |
| 19 | + <li>如果机器人往 <strong>左</strong> 或者往 <strong>右</strong> 移动到第 <code>c</code> <strong>列</strong> 的格子,那么代价为 <code>colCosts[c]</code> 。</li> |
| 20 | +</ul> |
| 21 | + |
| 22 | +<p>请你返回机器人回家需要的 <strong>最小总代价</strong> 。</p> |
| 23 | + |
| 24 | +<p> </p> |
| 25 | + |
| 26 | +<p><strong>示例 1:</strong></p> |
| 27 | + |
| 28 | +<p><img alt="" src="https://assets.leetcode.com/uploads/2021/10/11/eg-1.png" style="width: 282px; height: 217px;"></p> |
| 29 | + |
| 30 | +<pre><strong>输入:</strong>startPos = [1, 0], homePos = [2, 3], rowCosts = [5, 4, 3], colCosts = [8, 2, 6, 7] |
| 31 | +<b>输出:</b>18 |
| 32 | +<b>解释:</b>一个最优路径为: |
| 33 | +从 (1, 0) 开始 |
| 34 | +-> 往下走到 (<em><strong>2</strong></em>, 0) 。代价为 rowCosts[2] = 3 。 |
| 35 | +-> 往右走到 (2, <em><strong>1</strong></em>) 。代价为 colCosts[1] = 2 。 |
| 36 | +-> 往右走到 (2, <em><strong>2</strong></em>) 。代价为 colCosts[2] = 6 。 |
| 37 | +-> 往右走到 (2, <em><strong>3</strong></em>) 。代价为 colCosts[3] = 7 。 |
| 38 | +总代价为 3 + 2 + 6 + 7 = 18</pre> |
| 39 | + |
| 40 | +<p><strong>示例 2:</strong></p> |
| 41 | + |
| 42 | +<pre><b>输入:</b>startPos = [0, 0], homePos = [0, 0], rowCosts = [5], colCosts = [26] |
| 43 | +<b>输出:</b>0 |
| 44 | +<b>解释:</b>机器人已经在家了,所以不需要移动。总代价为 0 。 |
| 45 | +</pre> |
| 46 | + |
| 47 | +<p> </p> |
| 48 | + |
| 49 | +<p><strong>提示:</strong></p> |
| 50 | + |
| 51 | +<ul> |
| 52 | + <li><code>m == rowCosts.length</code></li> |
| 53 | + <li><code>n == colCosts.length</code></li> |
| 54 | + <li><code>1 <= m, n <= 10<sup>5</sup></code></li> |
| 55 | + <li><code>0 <= rowCosts[r], colCosts[c] <= 10<sup>4</sup></code></li> |
| 56 | + <li><code>startPos.length == 2</code></li> |
| 57 | + <li><code>homePos.length == 2</code></li> |
| 58 | + <li><code>0 <= start<sub>row</sub>, home<sub>row</sub> < m</code></li> |
| 59 | + <li><code>0 <= start<sub>col</sub>, home<sub>col</sub> < n</code></li> |
| 60 | +</ul> |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +## 解题方法:脑筋急转弯(固定走法) |
| 65 | + |
| 66 | +想想我们是怎么计算代价的,如果上下移动到了某一行,不论是在哪一列移动到的,都加上这一行的“代价”;列同理。 |
| 67 | + |
| 68 | +假设起点终点不在同一行,那么竖直方向上从起点到终点的移动是不可避免的。并且我们没有必要往上移动后再往下移动这样来回绕路;竖直方向同理。 |
| 69 | + |
| 70 | +也就是说,任何场景我们都直接像样例中那样一个L形路径走过去就行了。 |
| 71 | + |
| 72 | ++ 时间复杂度$\mathcal{O}(|start_{row} - home_{row}| + |start_{col} - home_{col}|)$ |
| 73 | ++ 空间复杂度$\mathcal{O}(1)$,前提是不使用python普通切片改为循环 |
| 74 | + |
| 75 | +### AC代码 |
| 76 | + |
| 77 | +#### C++ |
| 78 | + |
| 79 | +$(起点, 终点]$ |
| 80 | + |
| 81 | +```cpp |
| 82 | +/* |
| 83 | + * @LastEditTime: 2026-04-04 14:05:23 |
| 84 | + */ |
| 85 | +class Solution { |
| 86 | +public: |
| 87 | + int minCost(vector<int>& startPos, vector<int>& homePos, vector<int>& rowCosts, vector<int>& colCosts) { |
| 88 | + int ans = 0; |
| 89 | + for (int from = startPos[0], to = homePos[0], direction = to > from ? 1 : -1; from != to; from += direction) { |
| 90 | + ans += rowCosts[from + direction]; |
| 91 | + } |
| 92 | + for (int from = startPos[1], to = homePos[1], direction = to > from ? 1 : -1; from != to; from += direction) { |
| 93 | + ans += colCosts[from + direction]; |
| 94 | + } |
| 95 | + return ans; |
| 96 | + } |
| 97 | +}; |
| 98 | +``` |
| 99 | +
|
| 100 | +#### Python |
| 101 | +
|
| 102 | +$[起点, 终点] - 起点$ |
| 103 | +
|
| 104 | +```python |
| 105 | +''' |
| 106 | +LastEditTime: 2026-04-04 14:10:12 |
| 107 | +''' |
| 108 | +from typing import List |
| 109 | +
|
| 110 | +class Solution: |
| 111 | + def minCost(self, startPos: List[int], homePos: List[int], rowCosts: List[int], colCosts: List[int]) -> int: |
| 112 | + sx, sy = startPos |
| 113 | + ex, ey = homePos |
| 114 | + return sum(rowCosts[min(sx, ex) : max(sx, ex) + 1]) + sum(colCosts[min(sy, ey) : max(sy, ey) + 1]) - rowCosts[sx] - colCosts[sy] |
| 115 | +``` |
| 116 | + |
| 117 | +python切片会拷贝不可变元素 |
| 118 | + |
| 119 | +```python |
| 120 | +>>> a = [1, 2, 3, 4] |
| 121 | +>>> b = a[1:3] |
| 122 | +>>> print(b) |
| 123 | +[2, 3] |
| 124 | +>>> b[0] = 0 |
| 125 | +>>> print(b) |
| 126 | +[0, 3] |
| 127 | +>>> print(a) |
| 128 | +[1, 2, 3, 4] |
| 129 | +``` |
| 130 | + |
| 131 | +<details><summary>啥都没说系列</summary>虽说是固定走法,但其实是固定中又偏自由的走法。<br/>可先左再下,也可先下再左,也可一左一下,反正拐弯不要钱,只要别同时存在往左和往右就好了。</details> |
| 132 | + |
| 133 | +> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/159828365)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接](https://blog.letmefly.xyz/2026/04/04/LeetCode%202087.%E7%BD%91%E6%A0%BC%E5%9B%BE%E4%B8%AD%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%9B%9E%E5%AE%B6%E7%9A%84%E6%9C%80%E5%B0%8F%E4%BB%A3%E4%BB%B7/)哦~ |
| 134 | +> |
| 135 | +> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode) |
0 commit comments