30 Day Challenge Day 21 | Leetcode 1197. Minimum Knight Moves
class Solution {
public:
int minKnightMoves(int x, int y) {
int steps = 0;
unordered_set<string> s;
queue<pair<int, int>> q;
q.push({0, 0});
s.insert(to_string(0) + '-' + to_string(0));
int dirs[8][2] = {{-2, 1},
{-2, -1},
{2, 1},
{2, -1},
{-1, 2},
{-1, -2},
{1, 2},
{1, -2}
};
while(!q.empty()) {
int sz = q.size();
for(int i = 0; i < sz; i++) {
auto t = q.front();
q.pop();
if(t.first == x && t.second == y) return steps;
for(int k = 0; k < 8; k++) {
int next_x = t.first + dirs[k][0];
int next_y = t.second + dirs[k][1];
if(!s.count(to_string(next_x) + '-' + to_string(next_y))) {
q.push({next_x, next_y});
s.insert(to_string(next_x) + '-' + to_string(next_y));
}
}
}
steps++;
}
return -1;
}
};
改进:
利用对称性:四个象限的坐标是具有无符号对称性的。那么不考虑象限,或者把所有坐标转换到第一象限,是不影响结果的。
class Solution {
public:
int minKnightMoves(int x, int y) {
// reduce the search space
x = abs(x);
y = abs(y);
int steps = 0;
unordered_set<string> s;
queue<pair<int, int>> q;
q.push({0, 0});
s.insert(to_string(0) + '-' + to_string(0));
int dirs[8][2] = {{-2, 1},
{-2, -1},
{2, 1},
{2, -1},
{-1, 2},
{-1, -2},
{1, 2},
{1, -2}
};
while(!q.empty()) {
int sz = q.size();
for(int i = 0; i < sz; i++) {
auto t = q.front();
q.pop();
if(t.first == x && t.second == y) return steps;
for(int k = 0; k < 8; k++) {
int next_x = t.first + dirs[k][0];
int next_y = t.second + dirs[k][1];
if(!s.count(to_string(next_x) + '-' + to_string(next_y))
&& next_x >= -2 && next_y >= -2 && next_x < x+2 && next_y < y+2) { // reduce the search space
q.push({next_x, next_y});
s.insert(to_string(next_x) + '-' + to_string(next_y));
}
}
}
steps++;
}
return -1;
}
};