-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathk_closest_points_to_origin_test.dart
116 lines (98 loc) · 2.63 KB
/
k_closest_points_to_origin_test.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import 'dart:math';
import 'package:collection/collection.dart';
import 'package:test/test.dart';
/// Given an array of points where points[i] = [xi, yi]
/// represents a point on the X-Y plane and an integer k, return the
/// closest points to the origin (0, 0).
///
/// The distance between two points on the X-Y plane is
/// the Euclidean distance (i.e., √(x1 - x2)2 + (y1 - y2)2).
///
/// You may return the answer in any order.
/// The answer is guaranteed to be unique (except for the order that it is in).
Iterable<Point> kClosest(List<Point> points, int k) sync* {
// quick select
}
Iterable<Point> kClosestHeapSimple(List<Point> points, int k) sync* {
final heap = HeapPriorityQueue<Point>(minFirst);
heap.addAll(points);
var i = 0;
while (i < k) {
yield heap.removeFirst();
i++;
}
}
Iterable<Point> kClosestHeapEfficient(List<Point> points, int k) sync* {
final heap = HeapPriorityQueue<Point>(maxFirst);
var n = points.length, i = 0;
while (i < k) heap.add(points[i++]);
while (i < n)
heap
..add(points[i++])
..removeFirst();
while (heap.isNotEmpty) yield heap.removeFirst();
}
Iterable<Point> kClosestSort(List<Point> points, int k) {
points.sort(minFirst);
return points.take(k);
}
extension on double {
int toSortInt() => this > 0 ? 1 : -1;
}
int minFirst(Point a, Point b) => (a.distance - b.distance).toSortInt();
int maxFirst(Point a, Point b) => (b.distance - a.distance).toSortInt();
class Point {
const Point(this.x, this.y);
final int x;
final int y;
// This would also be enough, actually, but distance "reads nicer".
// int get distanceSquared => x * x + y * y;
double get distance => sqrt(x * x + y * y);
@override
bool operator ==(Object o) => o is Point && o.x == x && o.y == y;
@override
int get hashCode => Object.hash(x, y);
@override
String toString() => 'Point($x, $y)';
}
void main() {
test('leetcode examples', () {
expect(
kClosest(
[Point(1, 3), Point(-2, 2)],
1,
).toSet(),
{Point(-2, 2)},
);
expect(
kClosest(
[Point(3, 3), Point(5, -1), Point(-2, 4)],
2,
),
{Point(3, 3), Point(-2, 4)},
);
});
test('other examples', () {
expect(
kClosest(
[
Point(1, 3),
Point(-2, 2),
Point(9, 9),
Point(0, 1),
Point(-1, 0),
Point(0, 0),
],
3,
).toSet(),
{Point(0, 0), Point(0, 1), Point(-1, 0)},
);
expect(
kClosest(
[Point(3, 3), Point(5, -1), Point(-2, 4)],
3,
).toSet(),
{Point(3, 3), Point(-2, 4), Point(5, -1)},
);
});
}