Skip to content

Commit

Permalink
Add solution and test-cases for problem 1368
Browse files Browse the repository at this point in the history
  • Loading branch information
0xff-dev committed Jan 18, 2025
1 parent d569e0c commit 0337aae
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 8 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# [1368.Minimum Cost to Make at Least One Valid Path in a Grid][title]

## Description
Given an `m x n` grid. Each cell of the grid has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of `grid[i][j]` can be:

- `1` which means go to the cell to the right. (i.e go from `grid[i][j]` to `grid[i][j + 1]`)
- `2` which means go to the cell to the left. (i.e go from `grid[i][j]` to `grid[i][j - 1]`)
- `3` which means go to the lower cell. (i.e go from `grid[i][j]` to `grid[i + 1][j]`)
- `4` which means go to the upper cell. (i.e go from `grid[i][j]` to `grid[i - 1][j]`)

Notice that there could be some signs on the cells of the grid that point outside the grid.

You will initially start at the upper left cell (`0, 0`). A valid path in the grid is a path that starts from the upper left cell (`0, 0`) and ends at the bottom-right cell (`m - 1, n - 1`) following the signs on the grid. The valid path does not have to be the shortest.

You can modify the sign on a cell with `cost = 1`. You can modify the sign on a cell **one time only**.

Return the minimum cost to make the grid have at least one valid path.

**Example 1:**

![1](./1.png)

```
Input: grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
Output: 3
Explanation: You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --> (0, 1) --> (0, 2) --> (0, 3) change the arrow to down with cost = 1 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0) change the arrow to down with cost = 1 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3) change the arrow to down with cost = 1 --> (3, 3)
The total cost = 3.
```

**Example 2:**

![2](./2.png)

```
Input: grid = [[1,1,3],[3,2,2],[1,1,4]]
Output: 0
Explanation: You can follow the path from (0, 0) to (2, 2).
```

**Example 3:**

![3](./3.png)

```
Input: grid = [[1,2],[4,3]]
Output: 1
```

## 结语

如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me]

[title]: https://leetcode.com/problems/minimum-cost-to-make-at-least-one-valid-path-in-a-grid
[me]: https://github.com/kylesliu/awesome-golang-algorithm
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
package Solution

func Solution(x bool) bool {
import "container/heap"

// x, y, cost, dir
type heap1368 [][4]int

func (h *heap1368) Len() int {
return len(*h)
}
func (h *heap1368) Swap(i, j int) {
(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
}

func (h *heap1368) Less(i, j int) bool {
return (*h)[i][2] < (*h)[j][2]
}
func (h *heap1368) Push(x any) {
*h = append(*h, x.([4]int))
}

func (h *heap1368) Pop() any {
old := *h
l := len(old)
x := old[l-1]
*h = old[:l-1]
return x
}

var dir1368 = [4][2]int{
{0, 1}, {0, -1}, {1, 0}, {-1, 0},
}

func Solution(grid [][]int) int {
m, n := len(grid), len(grid[0])
if m == 1 && n == 1 {
return 0
}
inf := m*n + 1
dp := make([][]int, m)
for i := range m {
dp[i] = make([]int, n)
for j := range n {
dp[i][j] = inf
}
}
// 就是优先队列
dp[0][0] = 0
h := &heap1368{}
if grid[0][0]&1 == 0 {
dp[0][0] = 1
heap.Push(h, [4]int{0, 0, 1, 1})
heap.Push(h, [4]int{0, 0, 1, 3})
} else {
heap.Push(h, [4]int{0, 0, 0, grid[0][0]})
}
for h.Len() > 0 {
cur := heap.Pop(h).([4]int)
if cur[0] == m-1 && cur[1] == n-1 {
return cur[2]
}
for i, d := range dir1368 {
nx, ny := cur[0]+d[0], cur[1]+d[1]
if nx < m && nx >= 0 && ny < n && ny >= 0 {
cost := cur[2]
if i != cur[3]-1 {
cost++
}
if dp[nx][ny] > cost {
dp[nx][ny] = cost
heap.Push(h, [4]int{nx, ny, cost, grid[nx][ny]})
}
}
}
}

return -1
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
inputs [][]int
expect int
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", [][]int{{1, 1, 1, 1}, {2, 2, 2, 2}, {1, 1, 1, 1}, {2, 2, 2, 2}}, 3},
{"TestCase2", [][]int{{1, 1, 3}, {3, 2, 2}, {1, 1, 4}}, 0},
{"TestCase3", [][]int{{1, 2}, {4, 3}}, 1},
}

// 开始测试
Expand All @@ -30,10 +30,10 @@ func TestSolution(t *testing.T) {
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}

0 comments on commit 0337aae

Please sign in to comment.