Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e052556

Browse files
committedApr 7, 2025
Add solution #1263
1 parent 03d2ae6 commit e052556

File tree

2 files changed

+97
-1
lines changed

2 files changed

+97
-1
lines changed
 

‎README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 1,202 LeetCode solutions in JavaScript
1+
# 1,203 LeetCode solutions in JavaScript
22

33
[https://leetcodejavascript.com](https://leetcodejavascript.com)
44

@@ -961,6 +961,7 @@
961961
1260|[Shift 2D Grid](./solutions/1260-shift-2d-grid.js)|Easy|
962962
1261|[Find Elements in a Contaminated Binary Tree](./solutions/1261-find-elements-in-a-contaminated-binary-tree.js)|Medium|
963963
1262|[Greatest Sum Divisible by Three](./solutions/1262-greatest-sum-divisible-by-three.js)|Medium|
964+
1263|[Minimum Moves to Move a Box to Their Target Location](./solutions/1263-minimum-moves-to-move-a-box-to-their-target-location.js)|Hard|
964965
1267|[Count Servers that Communicate](./solutions/1267-count-servers-that-communicate.js)|Medium|
965966
1268|[Search Suggestions System](./solutions/1268-search-suggestions-system.js)|Medium|
966967
1287|[Element Appearing More Than 25% In Sorted Array](./solutions/1287-element-appearing-more-than-25-in-sorted-array.js)|Easy|
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* 1263. Minimum Moves to Move a Box to Their Target Location
3+
* https://leetcode.com/problems/minimum-moves-to-move-a-box-to-their-target-location/
4+
* Difficulty: Hard
5+
*
6+
* A storekeeper is a game in which the player pushes boxes around in a warehouse trying to get
7+
* them to target locations.
8+
*
9+
* The game is represented by an m x n grid of characters grid where each element is a wall, floor,
10+
* or box.
11+
*
12+
* Your task is to move the box 'B' to the target position 'T' under the following rules:
13+
* - The character 'S' represents the player. The player can move up, down, left, right in grid if
14+
* it is a floor (empty cell).
15+
* - The character '.' represents the floor which means a free cell to walk.
16+
* - The character '#' represents the wall which means an obstacle (impossible to walk there).
17+
* - There is only one box 'B' and one target cell 'T' in the grid.
18+
* - The box can be moved to an adjacent free cell by standing next to the box and then moving in
19+
* the direction of the box. This is a push.
20+
* - The player cannot walk through the box.
21+
*
22+
* Return the minimum number of pushes to move the box to the target. If there is no way to reach
23+
* the target, return -1.
24+
*/
25+
26+
/**
27+
* @param {character[][]} grid
28+
* @return {number}
29+
*/
30+
var minPushBox = function(grid) {
31+
const rows = grid.length;
32+
const cols = grid[0].length;
33+
let player;
34+
let box;
35+
let target;
36+
37+
for (let i = 0; i < rows; i++) {
38+
for (let j = 0; j < cols; j++) {
39+
if (grid[i][j] === 'S') player = [i, j];
40+
if (grid[i][j] === 'B') box = [i, j];
41+
if (grid[i][j] === 'T') target = [i, j];
42+
}
43+
}
44+
45+
const queue = [[...box, ...player, 0]];
46+
const seen = new Set([`${box}-${player}`]);
47+
const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
48+
49+
function canReach(src, dst, fixedBox) {
50+
const visited = new Set();
51+
const stack = [src];
52+
53+
while (stack.length) {
54+
const [r, c] = stack.pop();
55+
if (r === dst[0] && c === dst[1]) return true;
56+
if (visited.has(`${r}-${c}`)) continue;
57+
visited.add(`${r}-${c}`);
58+
59+
for (const [dr, dc] of directions) {
60+
const nr = r + dr;
61+
const nc = c + dc;
62+
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols || grid[nr][nc] === '#'
63+
|| (nr === fixedBox[0] && nc === fixedBox[1])) continue;
64+
stack.push([nr, nc]);
65+
}
66+
}
67+
return false;
68+
}
69+
70+
while (queue.length) {
71+
const [boxRow, boxCol, playerRow, playerCol, pushes] = queue.shift();
72+
if (boxRow === target[0] && boxCol === target[1]) return pushes;
73+
74+
for (const [dr, dc] of directions) {
75+
const newBoxRow = boxRow + dr;
76+
const newBoxCol = boxCol + dc;
77+
const newPlayerRow = boxRow - dr;
78+
const newPlayerCol = boxCol - dc;
79+
80+
if (newBoxRow < 0 || newBoxRow >= rows || newBoxCol < 0 || newBoxCol >= cols
81+
|| grid[newBoxRow][newBoxCol] === '#') continue;
82+
if (!canReach([playerRow, playerCol], [newPlayerRow, newPlayerCol], [boxRow, boxCol])) {
83+
continue;
84+
}
85+
86+
const state = `${newBoxRow}-${newBoxCol}-${newPlayerRow}-${newPlayerCol}`;
87+
if (seen.has(state)) continue;
88+
89+
seen.add(state);
90+
queue.push([newBoxRow, newBoxCol, newPlayerRow, newPlayerCol, pushes + 1]);
91+
}
92+
}
93+
94+
return -1;
95+
};

0 commit comments

Comments
 (0)
Please sign in to comment.