-
Notifications
You must be signed in to change notification settings - Fork 120
/
Copy path0773-SlidingPuzzle.cs
136 lines (112 loc) · 4.02 KB
/
0773-SlidingPuzzle.cs
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//-----------------------------------------------------------------------------
// Runtime: 112ms
// Memory Usage: 27.2 MB
// Link: https://leetcode.com/submissions/detail/371657822/
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace LeetCode
{
public class _0773_SlidingPuzzle
{
private (int dr, int dc)[] direction = new (int dr, int dc)[4] { (1, 0), (-1, 0), (0, 1), (0, -1) };
public int SlidingPuzzle(int[][] board)
{
State final = new State(new int[2][]
{
new int[] { 1, 2, 3 },
new int[] { 4, 5, 0 },
});
State initState = new State(board);
Queue<State> queue = new Queue<State>();
ISet<State> visited = new HashSet<State>();
queue.Enqueue(initState);
visited.Add(initState);
int count = 0;
while (queue.Count > 0)
{
int size = queue.Count;
for (int i = 0; i < size; i++)
{
var curr = queue.Dequeue();
if (curr.Equals(final)) return count;
foreach (var dir in direction)
{
var next = curr.Move(dir);
if (next != null && visited.Add(next))
{
queue.Enqueue(next);
}
}
}
count++;
}
return -1;
}
private class State : IEquatable<State>
{
private readonly int[][] _board;
public State(int[][] board)
{
_board = board;
}
public override bool Equals(object obj) => Equals(obj as State);
public override int GetHashCode()
{
unchecked
{
int res = 0;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
{
res *= 10;
res += _board[i][j];
}
return res.GetHashCode();
}
}
public bool Equals(State other)
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
if (_board[i][j] != other._board[i][j])
return false;
return true;
}
private State Clone()
{
int[][] newBoard = new int[2][];
for (int i = 0; i < 2; i++)
{
newBoard[i] = new int[3];
for (int j = 0; j < 3; j++)
newBoard[i][j] = _board[i][j];
}
return new State(newBoard);
}
public State Move((int dr, int dc) dir)
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
if (_board[i][j] == 0)
{
int newI = i + dir.dr;
int newJ = j + dir.dc;
if (newI >= 0 && newI < 2 && newJ >= 0 && newJ < 3)
{
var tmp = _board[i][j];
_board[i][j] = _board[newI][newJ];
_board[newI][newJ] = tmp;
State res = Clone();
tmp = _board[i][j];
_board[i][j] = _board[newI][newJ];
_board[newI][newJ] = tmp;
return res;
}
return null;
}
return null;
}
}
}
}