Given n Circles present in x-y plane such that all the circles have their center aligned on the x-axis.
The task is to remove some of them, such that no two circles are intersecting. Find the minimum number of circles that need to be removed.
Note : Touching circles are also considered to be intersecting.
Given N and an array of pair of integers. Each pair contains two integers c and r each, denoting the circle with radius r and centre (c, 0).
Examples:
Input : N=4, arr={(1, 1), (2, 1), (3, 1), (4, 1)}
Output : 2
Remove 2nd and 3rd circle to make the circles non-intersecting.
Input : N=4, arr={(1, 1), (4, 1), (5, 2), (7, 1)}
Output : 1
Approach:
Greedy strategy can be applied to solve the problem.
- Find starting and ending points of the diameter of the circles.
- Starting point would be equal to (c-r) and ending point would be equal to (c+r) where (c, 0) is the centre of the particular circle and r is its radius.
- Sort the {start, end} pair according to the value of end point. Less the value of end point, less is its index.
- Start iterating the pairs and if the starting point of a circle is less than current end value, it means circles are intersecting hence increment the count. Else update the current end value.
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <algorithm> #include <iostream> using namespace std;
struct circle {
int start, end;
}; // Comparison function modified // according to the end value bool comp(circle a, circle b)
{ if (a.end == b.end)
return a.start < b.start;
return a.end < b.end;
} // Function to return the count // of non intersecting circles void CountCircles( int c[], int r[], int n)
{ // structure with start and
// end of diameter of circles
circle diameter[n];
for ( int i = 0; i < n; ++i) {
diameter[i].start = c[i] - r[i];
diameter[i].end = c[i] + r[i];
}
// sorting with smallest finish time first
sort(diameter, diameter + n, comp);
// count stores number of
// circles to be removed
int count = 0;
// cur stores ending of first circle
int cur = diameter[0].end;
for ( int i = 1; i < n; ++i) {
// non intersecting circles
if (diameter[i].start > cur) {
cur = diameter[i].end;
}
// intersecting circles
else
count++;
}
cout << count << "\n" ;
} // Driver Code int main()
{ // centers of circles
int c[] = { 1, 2, 3, 4 };
// radius of circles
int r[] = { 1, 1, 1, 1 };
// number of circles
int n = sizeof (c) / sizeof ( int );
CountCircles(c, r, n);
return 0;
} |
// Java implementation of the above approach import java.util.Arrays;
import java.util.Comparator;
public class MinimumCirclesTobeRemoved {
private class Circle implements Comparator<Circle>{
int start;
int end;
// Comparison function modified
// according to the end value
public int compare(Circle a , Circle b){
if (a.end == b.end){
return (a.start - b.start);
}
return a.end - b.end;
}
}
// Function to return the count
// of non intersecting circles
public void CountCircles( int [] c, int [] r, int n){
// structure with start and
// end of diameter of circles
Circle diameter[] = new Circle[n];
for ( int i = 0 ; i < n; i++)
{
diameter[i] = new Circle();
diameter[i].start = (c[i] - r[i]);
diameter[i].end = (c[i] + r[i]);
}
// sorting with smallest finish time first
Arrays.sort(diameter, new Circle());
// count stores number of
// circles to be removed
int count = 0 ;
// cur stores ending of first circle
int curr = diameter[ 0 ].end;
for ( int i = 1 ; i < n; i++)
{
// non intersecting circles
if (diameter[i].start > curr)
{
curr = diameter[i].end;
}
else
{
count++;
}
}
System.out.println(count);
}
// Driver code
public static void main(String[] args)
{
MinimumCirclesTobeRemoved a = new MinimumCirclesTobeRemoved();
// centers of circles
int [] c = new int []{ 1 , 2 , 3 , 4 };
// radius of circles
int [] r = new int []{ 1 , 1 , 1 , 1 };
a.CountCircles(c, r, c.length);
}
} // This code is contributed by parshavnahta97 |
# Python3 implementation of the above approach # Function to return the count # of non intersecting circles def CountCircles(c, r, n):
# Structure with start and
# end of diameter of circles
diameter = []
for i in range (n):
obj = []
obj.append(c[i] - r[i])
obj.append(c[i] + r[i])
diameter.append(obj)
# Sorting with smallest finish time first
diameter.sort()
# count stores number of
# circles to be removed
count = 0
# cur stores ending of first circle
cur = diameter[ 0 ][ 1 ]
for i in range ( 1 , n):
# Non intersecting circles
if (diameter[i][ 0 ] > cur):
cur = diameter[i][ 1 ]
# Intersecting circles
else :
count + = 1
print (count)
# Driver Code # Centers of circles c = [ 1 , 2 , 3 , 4 ]
# Radius of circles r = [ 1 , 1 , 1 , 1 ]
# Number of circles n = len (c)
CountCircles(c, r, n) # This code is contributed by rohitsingh07052 |
// Include namespace system using System;
using System.Linq;
using System.Collections;
public class MinimumCirclesTobeRemoved
{ private class Circle
{
public int start;
public int end;
}
// Function to return the count
// of non intersecting circles
public void CountCircles( int [] c, int [] r, int n)
{
// structure with start and
// end of diameter of circles
Circle[] diameter = new Circle[n];
for ( int i = 0; i < n; i++)
{
diameter[i] = new Circle();
diameter[i].start = (c[i] - r[i]);
diameter[i].end = (c[i] + r[i]);
}
// sorting with smallest finish time first
Array.Sort(diameter,(a,b)=>a.end==b.end ? a.start - b.start : a.end - b.end);
// count stores number of
// circles to be removed
var count = 0;
// cur stores ending of first circle
var curr = diameter[0].end;
for ( int i = 1; i < n; i++)
{
// non intersecting circles
if (diameter[i].start > curr)
{
curr = diameter[i].end;
}
else
{
count++;
}
}
Console.WriteLine(count);
}
// Driver code
public static void Main(String[] args)
{
var a = new MinimumCirclesTobeRemoved();
// centers of circles
int [] c = new int []{1, 2, 3, 4};
// radius of circles
int [] r = new int []{1, 1, 1, 1};
a.CountCircles(c, r, c.Length);
}
} // This code is contributed by aadityaburujwale. |
// JavaScript implementation of the above approach // Function to return the count // of non intersecting circles function CountCircles(c, r)
{ // structure with start and
// end of diameter of circles
let diameter = [];
for (let i = 0; i < c.length; ++i) {
diameter[i] = {start: c[i] - r[i], end: c[i] + r[i]};
}
// sorting with smallest finish time first
diameter.sort( function (a, b) {
if (a.end == b.end)
return a.start < b.start;
return a.end < b.end;
});
// count stores number of
// circles to be removed
let count = 0;
// cur stores ending of first circle
let cur = diameter[0].end;
for (let i = 1; i < diameter.length; ++i) {
// non intersecting circles
if (diameter[i].start > cur) {
cur = diameter[i].end;
}
// intersecting circles
else
count++;
}
console.log(count);
} // Driver Code // centers of circles let c = [1, 2, 3, 4]; // radius of circles let r = [1, 1, 1, 1]; // number of circles let n = c.length; CountCircles(c, r); // This code is contributed by akashish__ |
2
Time Complexity: O(N*log(N))
where N is the number of circles.
Space Complexity: O(N)