https://leetcode.com/problems/path-crossing
Intuition
Implement an unoptimized solution by just recording each traveled node.
NOTE: after a ton of analysis of the proposed solutions on l33tcode, I can confirm that this solution is actually quite well optimized - there does not seem to be a trick capable of detecting a crossing without recording each and every position
Approach
- Record each traveled node by combining X and Y into a single number and store in a HashSet
- Iterate through all characters in the array until a previously traveled node is encountered, then exit.
Complexity
Time complexity:
O(n)
(iterate through each position once)
Space complexity:
O(n)
(store each position as hash)
Code
public class Solution
{
class PointComparer : IEqualityComparer<System.Drawing.Point> {
public bool Equals(System.Drawing.Point x, System.Drawing.Point y) {
return x.X == y.X && x.Y == y.Y;
}
public int GetHashCode(System.Drawing.Point obj) {
return (obj.Y << 16) ^ obj.X;
}
}
private HashSet<System.Drawing.Point> hashes = new HashSet<System.Drawing.Point>(new PointComparer());
private System.Drawing.Point currentPos = new System.Drawing.Point(0,0);
private bool OccupyCurrentPos()
{
//Console.WriteLine($"Calculated hash {hash} for position {currentPos.X}, {currentPos.Y}");
if(hashes.Contains(currentPos))
return true;
hashes.Add(currentPos);
return false;
}
public bool IsPathCrossing(string path)
{
OccupyCurrentPos();
foreach(char c in path.ToLower())
{
switch(c)
{
case 'n':
currentPos.Y++;
break;
case 's':
currentPos.Y--;
break;
case 'e':
currentPos.X++;
break;
case 'w':
currentPos.X--;
break;
}
if(OccupyCurrentPos())
{
//Console.WriteLine($"Crossed at {currentPos.X},{currentPos.Y}");
return true;
}
}
return false;
}
}