Given a string path
, where path[i] = 'N'
, 'S'
, 'E'
or 'W'
, each representing moving one unit north, south, east, or west, respectively. You start at the origin (0, 0)
on a 2D plane and walk on the path specified by path
.
Return true
if the path crosses itself at any point, that is, if at any time you are on a location you have previously visited. Return false
otherwise.
Example 1:
Input: path = "NES" Output: false Explanation: Notice that the path doesn't cross any point more than once.
Example 2:
Input: path = "NESWW" Output: true Explanation: Notice that the path visits the origin twice.
Constraints:
1 <= path.length <= 104
path[i]
is either 'N'
, 'S'
, 'E'
, or 'W'
.This problem asks whether a path, represented by a string of 'N', 'S', 'E', and 'W' characters, crosses itself. The solution involves tracking the current coordinates and checking if they've been visited before.
Approach:
The most efficient approach is to use a hash set (or dictionary in Python) to store the visited coordinates. We start at the origin (0, 0). For each character in the path
string:
Update Coordinates: Based on the character ('N', 'S', 'E', 'W'), we update the x and y coordinates accordingly.
Check for Crossing: We check if the current coordinates are already present in the visited
set. If they are, it means the path has crossed itself, and we return true
.
Add to Visited: If the coordinates are not in the visited
set, we add them, and continue to the next character.
Return False: If the loop completes without finding a crossing, we return false
.
Time Complexity Analysis:
The time complexity is O(N), where N is the length of the path
string. This is because we iterate through the string once. Hash set lookups and insertions are, on average, O(1).
Space Complexity Analysis:
The space complexity is O(N) in the worst case. In the worst case, the path might never cross itself, and we store all the unique coordinates visited in the visited
set. The size of the set could be up to N.
Code Explanation (Python):
class Solution:
def isPathCrossing(self, path: str) -> bool:
i = j = 0 # Initialize coordinates to (0, 0)
vis = {(0, 0)} # Set to store visited coordinates, starting with (0,0)
for c in path: # Iterate through each character in the path string
match c: # python 3.10+ pattern matching
case 'N':
i -= 1
case 'S':
i += 1
case 'E':
j += 1
case 'W':
j -= 1
if (i, j) in vis: # Check if current coordinates are already visited
return True # If visited, path crosses itself
vis.add((i, j)) # Add current coordinates to the visited set
return False # If loop completes without crossing, return False
The other languages (Java, C++, Go, TypeScript) follow a similar approach, using the appropriate data structures for sets in each language. The core logic remains the same. The Java, C++, and Go examples use a more compact representation of the coordinates within the hash set to improve efficiency. They use a single integer to represent the coordinate pair (e.g., i * 20000 + j
). This is a common optimization when dealing with coordinate pairs and hash sets. The constant 20000
ensures a unique integer representation for reasonable coordinate values. Choosing an appropriate constant depends on the constraints of the problem (in this case, the constraint on path length helps determine this).