Valid Square

MediumMath · Geometry🧩 Math & GeometryLeetCode #593 ↗Updated

Problem

You get four points p1..p4 in the plane, each as [x, y], listed in no particular order. Return true if they are the corners of a square with a positive side length (the square may be rotated), otherwise false.
Inputp1=[0,0], p2=[1,1], p3=[1,0], p4=[0,1]Outputtrue
Inputp1=[0,0], p2=[1,1], p3=[1,0], p4=[0,12]Outputfalse
Inputp1=[1,0], p2=[-1,0], p3=[0,1], p4=[0,-1]Outputtrue

each point has 2 integer coordinates  ·  -104 ≤ x, y ≤ 104  ·  the square can be tilted at any angle

Try it yourself

Java
class Solution {
    public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A square is fully described by its six pairwise distances: four equal positive sides and two equal diagonals, each diagonal² = 2 × side². No angles, no ordering — just compare squared distances in integers.
PatternMath & Geometry

Instinct Digits, factors, slopes or distances hide a formula - find the invariant, then guard against overflow, negatives and floating-point error.

Memory hack Mod peels, gcd reduces, squares compare - and long saves the day. Peel digits with %10, reduce slopes with gcd, compare squared distances.

Open the Math & Geometry guide →

Approaches

Brute ForceTry Every Ordering of the Corners

Time O(1)Space O(1)

Since we don't know which corner follows which, try all 4! = 24 orderings a→b→c→d. An ordering is a square if its four sides share one positive squared length s and both diagonals equal 2s (Pythagoras then forces right angles).

Java
public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
    int[][] pts = {p1, p2, p3, p4};
    for (int a = 0; a < 4; a++)
        for (int b = 0; b < 4; b++)
            for (int c = 0; c < 4; c++)
                for (int d = 0; d < 4; d++) {
                    if (a == b || a == c || a == d || b == c || b == d || c == d) continue;
                    if (isSquare(pts[a], pts[b], pts[c], pts[d])) return true;
                }
    return false;
}

// Corners in cycle order a -> b -> c -> d
private boolean isSquare(int[] a, int[] b, int[] c, int[] d) {
    long s = dist(a, b);
    return s > 0 && dist(b, c) == s && dist(c, d) == s && dist(d, a) == s
            && dist(a, c) == 2 * s && dist(b, d) == 2 * s;
}

private long dist(int[] p, int[] q) {
    long dx = p[0] - q[0], dy = p[1] - q[1];
    return dx * dx + dy * dy;
}

Constant time but 24 × 6 distance checks and a fiddly permutation loop.

At a glance

LevelApproachTimeSpace
Brute ForceTry Every Ordering of the CornersO(1)O(1)
BetterSort the Points to Fix the CycleO(1)O(1)
OptimalSix Pairwise DistancesO(1)O(1)
Common pitfalls
  • Allowing zero-length sides — four identical points have all distances equal (0).
  • Using Math.sqrt and comparing doubles — rounding breaks equality.
  • Assuming the input is in clockwise order — it is not; diagonals may be listed as sides.
Interview tips
  • Ask whether the order of points is guaranteed; that is what makes the problem tricky.
  • Argue why 4 equal sides + 2 equal diagonals is enough (rhombus with equal diagonals).
  • Mention the overflow check: max squared distance here is 8·108; long is safe.
Pattern
Geometry via invariants → describe a shape by order-free quantities (pairwise squared distances) instead of angles.
My notes saved in this browser