Minimum Circles needed to be removed so that all remaining circles are non intersecting
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++
// 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
// 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
# 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 |
C#
// 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
// 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)
Please Login to comment...