Problem#
Given two coordinates (x1, y1)
and (x2, y2)
, construct the equation of the line that passes through both points.
The line through two distinct points can be written in point-slope form:
where the slope m = (y2 - y1) / (x2 - x1)
. For a vertical line (x1 == x2
) the equation is x = x1
.
Examples#
Example 1#
1
2
3
Input: ( x1, y1) = ( 3 , 7 ), ( x2, y2) = ( 5 , 11 )
Output: y = 2 x + 1
Explanation: slope = ( 11 - 7 )/( 5 - 3 ) = 2 , intercept = 7 - 2 * 3 = 1
Example 2#
1
2
3
Input: ( x1, y1) = ( 2 , 2 ), ( x2, y2) = ( 4 , 12 )
Output: y = 5 x - 8
Explanation: slope = ( 12 - 2 )/( 4 - 2 ) = 5 , intercept = 2 - 5 * 2 = - 8
Similar Problems
Solution#
Method 1 - Point-slope (direct computation)#
Intuition#
Two distinct points uniquely define a line. Compute the slope m using the two points and substitute into point-slope form to obtain the line equation. If the two points share the same x-coordinate the line is vertical and described by x = c
.
Approach#
If (x1 == x2) return the vertical line x = x1
.
Compute slope m = (y2 - y1) / (x2 - x1) using floating-point arithmetic to handle non-integer slopes.
Compute intercept b = y1 - m * x1.
Return the line as (slope, intercept) or as a formatted equation y = m x + b
.
Edge cases:
Identical points (x1 == x2 and y1 == y2): the line is undefined (infinite number of lines); treat as a degenerate input — you can return None
or indicate the points are identical.
Code#
Cpp
Go
Java
Kotlin
Python
Rust
Typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public :
struct Point { double x, y; };
struct Line {
bool vertical;
double slope, intercept, x;
Line(double s, double c): vertical(false), slope(s), intercept(c), x(NAN) {}
Line(double xv): vertical(true), slope(NAN), intercept(NAN), x(xv) {}
};
Line lineFromPoints (const Point& a, const Point& b) {
const double EPS = 1e-12 ;
if (std:: abs(a.x - b.x) < EPS && std:: abs(a.y - b.y) < EPS) return Line(0.0 , 0.0 ); // identical: degenerate
if (std:: abs(a.x - b.x) < EPS) return Line(a.x); // vertical
double m = (b.y - a.y) / (b.x - a.x);
double c = a.y - m * a.x;
return Line(m, c);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
type Point struct { X , Y float64 }
type Line struct { Vertical bool ; Slope , Intercept , X float64 }
func abs (x float64 ) float64 { if x < 0 { return - x }; return x }
func LineFromPoints (a , b Point ) Line {
const EPS = 1e-12
if abs (a .X - b .X ) < EPS && abs (a .Y - b .Y ) < EPS { return Line {false , 0 , 0 , 0 } } // identical
if abs (a .X - b .X ) < EPS { return Line {true , 0 , 0 , a .X } }
m := (b .Y - a .Y ) / (b .X - a .X )
c := a .Y - m * a .X
return Line {false , m , c , 0 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
static final double EPS = 1e- 12;
static class Point { final double x, y; Point(double x, double y) { this .x = x; this .y = y; } }
static class Line {
final boolean vertical;
final double slope, intercept, x;
Line(double slope, double intercept) { this .vertical = false ; this .slope = slope; this .intercept = intercept; this .x = Double.NaN ; }
Line(double x) { this .vertical = true ; this .slope = Double.NaN ; this .intercept = Double.NaN ; this .x = x; }
}
public Line lineFromPoints (Point a, Point b) {
if (Math.abs (a.x - b.x ) < EPS && Math.abs (a.y - b.y ) < EPS) return null ; // identical points
if (Math.abs (a.x - b.x ) < EPS) return new Line(a.x ); // vertical
double m = (b.y - a.y ) / (b.x - a.x );
double c = a.y - m * a.x ;
return new Line(m, c);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
data class Point (val x: Double, val y: Double)
class Solution {
data class Line (val vertical: Boolean, val slope: Double, val intercept: Double, val x: Double)
fun lineFromPoints (a: Point, b: Point): Line? {
val eps = 1e-12
if (kotlin.math.abs(a.x - b.x) < eps && kotlin.math.abs(a.y - b.y) < eps) return null
if (kotlin.math.abs(a.x - b.x) < eps) return Line(true , Double .NaN, Double .NaN, a.x)
val m = (b.y - a.y) / (b.x - a.x)
val c = a.y - m * a.x
return Line(false , m, c, Double .NaN)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
class Solution :
def line_from_points (self, a: tuple[float, float], b: tuple[float, float]) -> tuple[float, float] | tuple[str, float] | None :
EPS = 1e-12
x1, y1 = a
x2, y2 = b
if abs(x1 - x2) < EPS and abs(y1 - y2) < EPS:
return None
if abs(x1 - x2) < EPS:
return ("vertical" , x1)
m = (y2 - y1) / (x2 - x1)
c = y1 - m * x1
return (m, c)
1
2
3
4
5
6
7
8
9
10
11
struct Point { x: f64 , y: f64 }
struct Line { vertical: bool , slope: f64 , intercept: f64 , x: f64 }
fn line_from_points (a: & Point , b: & Point ) -> Option< Line> {
let eps = 1e-12 ;
if (a.x - b.x).abs() < eps && (a.y - b.y).abs() < eps { return None; }
if (a.x - b.x).abs() < eps { return Some(Line { vertical: true , slope: f64 ::NAN , intercept: f64 ::NAN , x: a .x }); }
let m = (b.y - a.y) / (b.x - a.x);
let c = a.y - m * a.x;
Some(Line { vertical: false , slope: m , intercept: c , x: f64 ::NAN })
}
1
2
3
4
5
6
7
8
9
10
11
12
type Point = { x : number ; y : number };
type Line = { vertical : boolean ; slope? : number ; intercept? : number ; x? : number } | null ;
function lineFromPoints (a : Point , b : Point ): Line {
const EPS = 1 e - 12 ;
const abs = (v : number ) => (v < 0 ? - v : v );
if (abs (a .x - b .x ) < EPS && abs (a .y - b .y ) < EPS ) return null ;
if (abs (a .x - b .x ) < EPS ) return { vertical : true , x : a.x };
const m = (b .y - a .y ) / (b .x - a .x );
const c = a .y - m * a .x ;
return { vertical : false , slope : m , intercept : c };
}
Complexity#
⏰ Time complexity: O(1)
— Constant work to compute slope and intercept.
🧺 Space complexity: O(1)
— Constant extra space for result and temporaries.