Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an array of integers distance.
You start at the point (0, 0) on an X-Y plane, and you move distance[0] meters to the north, then distance[1] meters to the west, distance[2] meters to the south, distance[3] meters to the east, and so on. In other words, after each move, your direction changes counter-clockwise.
Return true if your path crosses itself or false if it does not.
Example 1:
Input: distance = [2,1,1,2] Output: true Explanation: The path crosses itself at the point (0, 1).
Example 2:
Input: distance = [1,2,3,4] Output: false Explanation: The path does not cross itself at any point.
Example 3:
Input: distance = [1,1,1,2,1] Output: true Explanation: The path crosses itself at the point (0, 0).
Constraints:
1 <= distance.length <= 1051 <= distance[i] <= 105Problem summary: You are given an array of integers distance. You start at the point (0, 0) on an X-Y plane, and you move distance[0] meters to the north, then distance[1] meters to the west, distance[2] meters to the south, distance[3] meters to the east, and so on. In other words, after each move, your direction changes counter-clockwise. Return true if your path crosses itself or false if it does not.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Math
[2,1,1,2]
[1,2,3,4]
[1,1,1,2,1]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #335: Self Crossing
class Solution {
public boolean isSelfCrossing(int[] distance) {
int[] d = distance;
for (int i = 3; i < d.length; ++i) {
if (d[i] >= d[i - 2] && d[i - 1] <= d[i - 3]) {
return true;
}
if (i >= 4 && d[i - 1] == d[i - 3] && d[i] + d[i - 4] >= d[i - 2]) {
return true;
}
if (i >= 5 && d[i - 2] >= d[i - 4] && d[i - 1] <= d[i - 3]
&& d[i] >= d[i - 2] - d[i - 4] && d[i - 1] + d[i - 5] >= d[i - 3]) {
return true;
}
}
return false;
}
}
// Accepted solution for LeetCode #335: Self Crossing
func isSelfCrossing(distance []int) bool {
d := distance
for i := 3; i < len(d); i++ {
if d[i] >= d[i-2] && d[i-1] <= d[i-3] {
return true
}
if i >= 4 && d[i-1] == d[i-3] && d[i]+d[i-4] >= d[i-2] {
return true
}
if i >= 5 && d[i-2] >= d[i-4] && d[i-1] <= d[i-3] && d[i] >= d[i-2]-d[i-4] && d[i-1]+d[i-5] >= d[i-3] {
return true
}
}
return false
}
# Accepted solution for LeetCode #335: Self Crossing
class Solution:
def isSelfCrossing(self, distance: List[int]) -> bool:
d = distance
for i in range(3, len(d)):
if d[i] >= d[i - 2] and d[i - 1] <= d[i - 3]:
return True
if i >= 4 and d[i - 1] == d[i - 3] and d[i] + d[i - 4] >= d[i - 2]:
return True
if (
i >= 5
and d[i - 2] >= d[i - 4]
and d[i - 1] <= d[i - 3]
and d[i] >= d[i - 2] - d[i - 4]
and d[i - 1] + d[i - 5] >= d[i - 3]
):
return True
return False
// Accepted solution for LeetCode #335: Self Crossing
/**
* [335] Self Crossing
*
* You are given an array of integers distance.
* You start at point (0,0) on an X-Y plane and you move distance[0] meters to the north, then distance[1] meters to the west, distance[2] meters to the south, distance[3] meters to the east, and so on. In other words, after each move, your direction changes counter-clockwise.
* Return true if your path crosses itself, and false if it does not.
*
* Example 1:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross1-plane.jpg" style="width: 400px; height: 435px;" />
* Input: distance = [2,1,1,2]
* Output: true
*
* Example 2:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross2-plane.jpg" style="width: 400px; height: 435px;" />
* Input: distance = [1,2,3,4]
* Output: false
*
* Example 3:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross3-plane.jpg" style="width: 400px; height: 435px;" />
* Input: distance = [1,1,1,1]
* Output: true
*
*
* Constraints:
*
* 1 <= distance.length <= 10^5
* 1 <= distance[i] <= 10^5
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/self-crossing/
// discuss: https://leetcode.com/problems/self-crossing/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
// Credit: https://leetcode.com/problems/self-crossing/discuss/79131/Java-Oms-with-explanation
pub fn is_self_crossing(distance: Vec<i32>) -> bool {
let l = distance.len();
if l <= 3 {
return false;
}
for i in 3..l {
if distance[i] >= distance[i - 2] && distance[i - 1] <= distance[i - 3] {
//Fourth line crosses first line and onward
return true;
}
if i >= 4 {
if distance[i - 1] == distance[i - 3]
&& distance[i] + distance[i - 4] >= distance[i - 2]
{
// Fifth line meets first line and onward
return true;
}
}
if i >= 5 {
if distance[i - 2] - distance[i - 4] >= 0
&& distance[i] >= distance[i - 2] - distance[i - 4]
&& distance[i - 1] >= distance[i - 3] - distance[i - 5]
&& distance[i - 1] <= distance[i - 3]
{
// Sixth line crosses first line and onward
return true;
}
}
}
false
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_0335_example_1() {
let distance = vec![2, 1, 1, 2];
let result = true;
assert_eq!(Solution::is_self_crossing(distance), result);
}
#[test]
fn test_0335_example_2() {
let distance = vec![1, 2, 3, 4];
let result = false;
assert_eq!(Solution::is_self_crossing(distance), result);
}
#[test]
fn test_0335_example_3() {
let distance = vec![1, 1, 1, 1];
let result = true;
assert_eq!(Solution::is_self_crossing(distance), result);
}
}
// Accepted solution for LeetCode #335: Self Crossing
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #335: Self Crossing
// class Solution {
// public boolean isSelfCrossing(int[] distance) {
// int[] d = distance;
// for (int i = 3; i < d.length; ++i) {
// if (d[i] >= d[i - 2] && d[i - 1] <= d[i - 3]) {
// return true;
// }
// if (i >= 4 && d[i - 1] == d[i - 3] && d[i] + d[i - 4] >= d[i - 2]) {
// return true;
// }
// if (i >= 5 && d[i - 2] >= d[i - 4] && d[i - 1] <= d[i - 3]
// && d[i] >= d[i - 2] - d[i - 4] && d[i - 1] + d[i - 5] >= d[i - 3]) {
// return true;
// }
// }
// return false;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.