Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.1610
Browse files Browse the repository at this point in the history
No.1610.Maximum Number of Visible Points
  • Loading branch information
yanglbme committed Dec 16, 2021
1 parent 2dcb5b3 commit 03128fd
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 4 deletions.
122 changes: 120 additions & 2 deletions solution/1600-1699/1610.Maximum Number of Visible Points/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,145 @@
<li><code>0 <= pos<sub>x</sub>, pos<sub>y</sub>, x<sub>i</sub>, y<sub>i</sub> <= 100</code></li>
</ul>


## 解法

<!-- 这里可写通用的实现逻辑 -->

根据题目我们得知,需要求出在视角范围 `[d - angle/2, d + angle / 2]` 范围内覆盖的最多点的数量。视角可以转换为相对于 location `(x, y)` 的极角。

可以排除与 location 重合的点,将剩下的所有点 p 的坐标 `(xi, yi)` 转换为相对于 `(x, y)` 的极角。可以利用 `atan2` 函数,`atan2` 返回值范围是 `[−π,π]`,覆盖范围是 2π。

求出极角后,按照大小进行排序。因为可以循环,所以把整个数组所有元素加上 2π 接在数组后面。

接下来利用双指针找出覆盖最多点的区间即可。最后返回时,要把重合的点加上。

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def visiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int:
v = []
x, y = location
same = 0
for xi, yi in points:
if xi == x and yi == y:
same += 1
else:
v.append(atan2(yi - y, xi - x))
v.sort()
n = len(v)
v += [deg + 2 * pi for deg in v]
t = angle * pi / 180
mx = max((bisect_right(v, v[i] + t) - i for i in range(n)), default=0)
return mx + same
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
List<Double> v = new ArrayList<>();
int x = location.get(0), y = location.get(1);
int same = 0;
for (List<Integer> p : points) {
int xi = p.get(0), yi = p.get(1);
if (xi == x && yi == y) {
++same;
continue;
}
v.add(Math.atan2(yi - y, xi - x));
}
Collections.sort(v);
int n = v.size();
for (int i = 0; i < n; ++i) {
v.add(v.get(i) + 2 * Math.PI);
}
int mx = 0;
Double t = angle * Math.PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j) {
while (i < j && v.get(j) - v.get(i) > t) {
++i;
}
mx = Math.max(mx, j - i + 1);
}
return mx + same;
}
}
```

### **C++**

```cpp
class Solution {
public:
int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
vector<double> v;
int x = location[0], y = location[1];
int same = 0;
for (auto& p : points)
{
int xi = p[0], yi = p[1];
if (xi == x && yi == y) ++same;
else v.emplace_back(atan2(yi - y, xi - x));
}
sort(v.begin(), v.end());
int n = v.size();
for (int i = 0; i < n; ++i) v.emplace_back(v[i] + 2 * M_PI);

int mx = 0;
double t = angle * M_PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j)
{
while (i < j && v[j] - v[i] > t) ++i;
mx = max(mx, j - i + 1);
}
return mx + same;
}
};
```

### **Go**

```go
func visiblePoints(points [][]int, angle int, location []int) int {
same := 0
v := []float64{}
for _, p := range points {
if p[0] == location[0] && p[1] == location[1] {
same++
} else {
v = append(v, math.Atan2(float64(p[1]-location[1]), float64(p[0]-location[0])))
}
}
sort.Float64s(v)
for _, deg := range v {
v = append(v, deg+2*math.Pi)
}

mx := 0
t := float64(angle) * math.Pi / 180
for i, j := 0, 0; j < len(v); j++ {
for i < j && v[j]-v[i] > t {
i++
}
mx = max(mx, j-i+1)
}
return same + mx
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

### **...**
Expand Down
114 changes: 112 additions & 2 deletions solution/1600-1699/1610.Maximum Number of Visible Points/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,131 @@
<li><code>0 &lt;= pos<sub>x</sub>, pos<sub>y</sub>, x<sub>i</sub>, y<sub>i</sub> &lt;= 100</code></li>
</ul>


## Solutions

<!-- tabs:start -->

### **Python3**

```python

class Solution:
def visiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int:
v = []
x, y = location
same = 0
for xi, yi in points:
if xi == x and yi == y:
same += 1
else:
v.append(atan2(yi - y, xi - x))
v.sort()
n = len(v)
v += [deg + 2 * pi for deg in v]
t = angle * pi / 180
mx = max((bisect_right(v, v[i] + t) - i for i in range(n)), default=0)
return mx + same
```

### **Java**

```java
class Solution {
public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
List<Double> v = new ArrayList<>();
int x = location.get(0), y = location.get(1);
int same = 0;
for (List<Integer> p : points) {
int xi = p.get(0), yi = p.get(1);
if (xi == x && yi == y) {
++same;
continue;
}
v.add(Math.atan2(yi - y, xi - x));
}
Collections.sort(v);
int n = v.size();
for (int i = 0; i < n; ++i) {
v.add(v.get(i) + 2 * Math.PI);
}
int mx = 0;
Double t = angle * Math.PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j) {
while (i < j && v.get(j) - v.get(i) > t) {
++i;
}
mx = Math.max(mx, j - i + 1);
}
return mx + same;
}
}
```

### **C++**

```cpp
class Solution {
public:
int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
vector<double> v;
int x = location[0], y = location[1];
int same = 0;
for (auto& p : points)
{
int xi = p[0], yi = p[1];
if (xi == x && yi == y) ++same;
else v.emplace_back(atan2(yi - y, xi - x));
}
sort(v.begin(), v.end());
int n = v.size();
for (int i = 0; i < n; ++i) v.emplace_back(v[i] + 2 * M_PI);

int mx = 0;
double t = angle * M_PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j)
{
while (i < j && v[j] - v[i] > t) ++i;
mx = max(mx, j - i + 1);
}
return mx + same;
}
};
```

### **Go**

```go
func visiblePoints(points [][]int, angle int, location []int) int {
same := 0
v := []float64{}
for _, p := range points {
if p[0] == location[0] && p[1] == location[1] {
same++
} else {
v = append(v, math.Atan2(float64(p[1]-location[1]), float64(p[0]-location[0])))
}
}
sort.Float64s(v)
for _, deg := range v {
v = append(v, deg+2*math.Pi)
}

mx := 0
t := float64(angle) * math.Pi / 180
for i, j := 0, 0; j < len(v); j++ {
for i < j && v[j]-v[i] > t {
i++
}
mx = max(mx, j-i+1)
}
return same + mx
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

### **...**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Solution {
public:
int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
vector<double> v;
int x = location[0], y = location[1];
int same = 0;
for (auto& p : points)
{
int xi = p[0], yi = p[1];
if (xi == x && yi == y) ++same;
else v.emplace_back(atan2(yi - y, xi - x));
}
sort(v.begin(), v.end());
int n = v.size();
for (int i = 0; i < n; ++i) v.emplace_back(v[i] + 2 * M_PI);

int mx = 0;
double t = angle * M_PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j)
{
while (i < j && v[j] - v[i] > t) ++i;
mx = max(mx, j - i + 1);
}
return mx + same;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
func visiblePoints(points [][]int, angle int, location []int) int {
same := 0
v := []float64{}
for _, p := range points {
if p[0] == location[0] && p[1] == location[1] {
same++
} else {
v = append(v, math.Atan2(float64(p[1]-location[1]), float64(p[0]-location[0])))
}
}
sort.Float64s(v)
for _, deg := range v {
v = append(v, deg+2*math.Pi)
}

mx := 0
t := float64(angle) * math.Pi / 180
for i, j := 0, 0; j < len(v); j++ {
for i < j && v[j]-v[i] > t {
i++
}
mx = max(mx, j-i+1)
}
return same + mx
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Solution {
public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
List<Double> v = new ArrayList<>();
int x = location.get(0), y = location.get(1);
int same = 0;
for (List<Integer> p : points) {
int xi = p.get(0), yi = p.get(1);
if (xi == x && yi == y) {
++same;
continue;
}
v.add(Math.atan2(yi - y, xi - x));
}
Collections.sort(v);
int n = v.size();
for (int i = 0; i < n; ++i) {
v.add(v.get(i) + 2 * Math.PI);
}
int mx = 0;
Double t = angle * Math.PI / 180;
for (int i = 0, j = 0; j < 2 * n; ++j) {
while (i < j && v.get(j) - v.get(i) > t) {
++i;
}
mx = Math.max(mx, j - i + 1);
}
return mx + same;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def visiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int:
v = []
x, y = location
same = 0
for xi, yi in points:
if xi == x and yi == y:
same += 1
else:
v.append(atan2(yi - y, xi - x))
v.sort()
n = len(v)
v += [deg + 2 * pi for deg in v]
t = angle * pi / 180
mx = max((bisect_right(v, v[i] + t) - i for i in range(n)), default=0)
return mx + same

0 comments on commit 03128fd

Please sign in to comment.