Open In App

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 :
 



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. 

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__

Output: 
2

 

Time Complexity: O(N*log(N)) 
where N is the number of circles.

Space Complexity: O(N)
 


Article Tags :