Przeglądaj źródła

feat: max_points_on_a_line

Zhang Li 11 miesięcy temu
rodzic
commit
5d5ce6694b

+ 63 - 0
src/solutions/other/max_points_on_a_line.rs

@@ -0,0 +1,63 @@
+struct Solution;
+impl Solution {
+    pub fn max_points(points: Vec<Vec<i32>>) -> i32 {
+        let mut ans = 1;
+        let l = points.len();
+        for i in 0..l-1 {
+            let point_a = &points[i];
+            let mut dup = 0;
+            let mut map = std::collections::HashMap::new();
+            for j in i+1..l {
+                let point_b = &points[j];
+                if point_a[0] == point_b[0] && point_a[1] ==  point_b[1] {
+                    dup += 1;
+                    continue;
+                }
+                let (dx, dy) = Self::get_slope(point_a,  point_b);
+                map.entry((dx, dy)).and_modify(|x| *x += 1).or_insert(1);
+
+            }
+            ans = ans.max(map.values().max().unwrap_or(&0) + 1 + dup);
+        }
+
+
+        ans
+    }
+
+    fn get_slope(p1: &Vec<i32>, p2: &Vec<i32>) -> (i32, i32) {
+        let (mut dx, mut dy) = (0, 0);
+        if p1[0] == p2[0] {
+            dx = p1[0];
+        } else if p1[1] == p2[1] {
+            dy = p1[1];
+        } else {
+            let gcd = Self::gcd(p2[1]-p1[1], p2[0]-p1[0]);
+            dx = (p2[0]-p1[0]) / gcd;
+            dy = (p2[1]-p1[1]) / gcd;
+        }
+
+        (dx, dy)
+    }
+    fn gcd(m: i32, n: i32) -> i32 {
+        if n == 0 {
+            m
+        } else {
+            Self::gcd(n, m%n)
+        }
+
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_max_points() {
+        let points = vec![vec![1,1],vec![3,2],vec![5,3],vec![4,1],vec![2,3],vec![1,4], vec![1,4]];
+
+        let res = Solution::max_points(points);
+        assert_eq!(res, 5);
+    }
+
+}

+ 2 - 1
src/solutions/other/mod.rs

@@ -7,4 +7,5 @@ mod spiral_matrix;
 mod spiral_matrix_2;
 mod valid_number;
 mod set_matrix_zero;
-mod gray_code;
+mod gray_code;
+mod max_points_on_a_line;