题目描述
给你两个整数 height
和 width
,代表一个大小为 height x width
的花园。你还得到了以下信息:
- 一个数组
tree
,其中 tree = [treer, treec]
是花园中树的位置,
- 一个数组
squirrel
,其中 squirrel = [squirrelr, squirrelc]
是花园中松鼠的位置,
- 一个数组
nuts
,其中 nuts[i] = [nutir, nutic]
是花园中第 ith
个坚果的位置。
松鼠一次最多只能携带一个坚果,并且能够向上、下、左、右四个方向移动到相邻的单元格。
返回松鼠收集所有坚果并逐一放在树下的 最小距离 。
距离 是指移动的次数。
示例 1:
输入:height = 5, width = 7, tree = [2,2], squirrel = [4,4], nuts = [[3,0], [2,5]]
输出:12
解释:为实现最小的距离,松鼠应该先摘 [2, 5] 位置的坚果。
示例 2:
输入:height = 1, width = 3, tree = [0,1], squirrel = [0,0], nuts = [[0,2]]
输出:3
提示:
1 <= height, width <= 100
tree.length == 2
squirrel.length == 2
1 <= nuts.length <= 5000
nuts[i].length == 2
0 <= treer, squirrelr, nutir <= height
0 <= treec, squirrelc, nutic <= width
解法
方法一:数学
我们观察松鼠的移动路径,可以发现,松鼠会首先移动到某个坚果的位置,然后移动到树的位置。接下来,松鼠的移动路径之和等于“其余坚果到树的位置之和”再乘以 $2$。
因此,我们只需要选出一个坚果,作为松鼠的第一个目标,使得其到树的位置之和最小,即可得到最小路径。
时间复杂度 $O(n)$,其中 $n$ 为坚果的数量。空间复杂度 $O(1)$。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | class Solution:
def minDistance(
self,
height: int,
width: int,
tree: List[int],
squirrel: List[int],
nuts: List[List[int]],
) -> int:
tr, tc = tree
sr, sc = squirrel
s = sum(abs(r - tr) + abs(c - tc) for r, c in nuts) * 2
ans = inf
for r, c in nuts:
a = abs(r - tr) + abs(c - tc)
b = abs(r - sr) + abs(c - sc)
ans = min(ans, s - a + b)
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import static java.lang.Math.*;
class Solution {
public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) {
int tr = tree[0], tc = tree[1];
int sr = squirrel[0], sc = squirrel[1];
int s = 0;
for (var e : nuts) {
s += abs(e[0] - tr) + abs(e[1] - tc);
}
s <<= 1;
int ans = Integer.MAX_VALUE;
for (var e : nuts) {
int a = abs(e[0] - tr) + abs(e[1] - tc);
int b = abs(e[0] - sr) + abs(e[1] - sc);
ans = min(ans, s - a + b);
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Solution {
public:
int minDistance(int height, int width, vector<int>& tree, vector<int>& squirrel, vector<vector<int>>& nuts) {
int tr = tree[0], tc = tree[1];
int sr = squirrel[0], sc = squirrel[1];
int s = 0;
for (const auto& e : nuts) {
s += abs(e[0] - tr) + abs(e[1] - tc);
}
s <<= 1;
int ans = INT_MAX;
for (const auto& e : nuts) {
int a = abs(e[0] - tr) + abs(e[1] - tc);
int b = abs(e[0] - sr) + abs(e[1] - sc);
ans = min(ans, s - a + b);
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | func minDistance(height int, width int, tree []int, squirrel []int, nuts [][]int) int {
tr, tc := tree[0], tree[1]
sr, sc := squirrel[0], squirrel[1]
s := 0
for _, e := range nuts {
s += abs(e[0]-tr) + abs(e[1]-tc)
}
s <<= 1
ans := math.MaxInt32
for _, e := range nuts {
a := abs(e[0]-tr) + abs(e[1]-tc)
b := abs(e[0]-sr) + abs(e[1]-sc)
ans = min(ans, s-a+b)
}
return ans
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | function minDistance(
height: number,
width: number,
tree: number[],
squirrel: number[],
nuts: number[][],
): number {
const [tr, tc] = tree;
const [sr, sc] = squirrel;
const s = nuts.reduce((acc, [r, c]) => acc + (Math.abs(tr - r) + Math.abs(tc - c)) * 2, 0);
let ans = Infinity;
for (const [r, c] of nuts) {
const a = Math.abs(tr - r) + Math.abs(tc - c);
const b = Math.abs(sr - r) + Math.abs(sc - c);
ans = Math.min(ans, s - a + b);
}
return ans;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | impl Solution {
pub fn min_distance(
height: i32,
width: i32,
tree: Vec<i32>,
squirrel: Vec<i32>,
nuts: Vec<Vec<i32>>,
) -> i32 {
let (tr, tc) = (tree[0], tree[1]);
let (sr, sc) = (squirrel[0], squirrel[1]);
let s: i32 = nuts
.iter()
.map(|nut| (nut[0] - tr).abs() + (nut[1] - tc).abs())
.sum::<i32>()
* 2;
let mut ans = i32::MAX;
for nut in &nuts {
let a = (nut[0] - tr).abs() + (nut[1] - tc).abs();
let b = (nut[0] - sr).abs() + (nut[1] - sc).abs();
ans = ans.min(s - a + b);
}
ans
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | public class Solution {
public int MinDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) {
int tr = tree[0], tc = tree[1];
int sr = squirrel[0], sc = squirrel[1];
int s = 0;
foreach (var e in nuts) {
s += Math.Abs(e[0] - tr) + Math.Abs(e[1] - tc);
}
s <<= 1;
int ans = int.MaxValue;
foreach (var e in nuts) {
int a = Math.Abs(e[0] - tr) + Math.Abs(e[1] - tc);
int b = Math.Abs(e[0] - sr) + Math.Abs(e[1] - sc);
ans = Math.Min(ans, s - a + b);
}
return ans;
}
}
|