class Solution:
def minDistance(self, height: int, width: int, tree: List[int], squirrel: List[int], nuts: List[List[int]]) -> int:
def dist(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
total = 0
max_diff = float('-inf')
for nut in nuts:
d_tree = dist(nut, tree)
d_squirrel = dist(nut, squirrel)
total += 2 * d_tree
max_diff = max(max_diff, d_tree - d_squirrel)
return total - max_diff
class Solution {
public:
int minDistance(int height, int width, vector& tree, vector& squirrel, vector<vector<int>>& nuts) {
auto dist = [](vector<int>& a, vector<int>& b) {
return abs(a[0] - b[0]) + abs(a[1] - b[1]);
};
int total = 0;
int maxDiff = INT_MIN;
for (auto& nut : nuts) {
int dTree = dist(nut, tree);
int dSquirrel = dist(nut, squirrel);
total += 2 * dTree;
maxDiff = max(maxDiff, dTree - dSquirrel);
}
return total - maxDiff;
}
};
class Solution {
public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) {
int total = 0;
int maxDiff = Integer.MIN_VALUE;
for (int[] nut : nuts) {
int dTree = Math.abs(nut[0] - tree[0]) + Math.abs(nut[1] - tree[1]);
int dSquirrel = Math.abs(nut[0] - squirrel[0]) + Math.abs(nut[1] - squirrel[1]);
total += 2 * dTree;
maxDiff = Math.max(maxDiff, dTree - dSquirrel);
}
return total - maxDiff;
}
}
var minDistance = function(height, width, tree, squirrel, nuts) {
function dist(a, b) {
return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);
}
let total = 0;
let maxDiff = -Infinity;
for (let nut of nuts) {
let dTree = dist(nut, tree);
let dSquirrel = dist(nut, squirrel);
total += 2 * dTree;
maxDiff = Math.max(maxDiff, dTree - dSquirrel);
}
return total - maxDiff;
};
In the Squirrel Simulation problem, you are given a 2D grid representing a park. There are several nuts on the grid, a single tree, and a squirrel at a starting position. The squirrel can move in four directions (up, down, left, right) and can carry only one nut at a time. The goal is for the squirrel to collect all the nuts and bring them to the tree, minimizing the total distance traveled.
height
and width
), the position of the tree (tree
), the squirrel's starting position (squirrel
), and a list of nut positions (nuts
).
At first glance, a brute-force approach might be to try all possible orders in which the squirrel can pick up the nuts. However, this quickly becomes infeasible as the number of nuts increases due to the factorial number of permutations.
A key observation is that after the first nut, the squirrel always starts from the tree. Only the first trip starts from the squirrel's initial position. Therefore, the only choice we need to make is: which nut should the squirrel pick up first? For each nut, we can compute the difference in distance between starting from the squirrel's position versus starting from the tree.
The optimal solution is to pick as the first nut the one for which this difference is maximized. This ensures the total distance is minimized.
d_tree
) and from the nut to the squirrel's starting position (d_squirrel
).
nut
to tree
) for each nut (go to nut, back to tree).
squirrel
to nut
plus nut
to tree
.
d_tree - d_squirrel
. We want to maximize this difference for the first nut, as it will reduce the total distance.
nut
to tree
) for all nuts
nut
to tree
- squirrel
to nut
) value
Let's say the grid is 5x7, the tree is at position [2,2], the squirrel starts at [4,4], and the nuts are at positions [[3,0],[2,5]].
nut
to tree
= |3-2| + |0-2| = 1 + 2 = 3; squirrel
to nut
= |4-3| + |4-0| = 1 + 4 = 5
nut
to tree
= |2-2| + |5-2| = 0 + 3 = 3; squirrel
to nut
= |4-2| + |4-5| = 2 + 1 = 3
The Squirrel Simulation problem can be solved efficiently by recognizing that only the first trip is special, and all subsequent trips start at the tree. By picking the nut that maximizes the saving on the first trip, we minimize the overall distance. This insight reduces the problem from a complex permutation to a simple linear scan, making the solution both elegant and efficient.