通过对相距最多为K的点进行分组,计算出不相交组的数量

291 阅读3分钟

通过对相距最远的K个点进行分组,计算出不相交组的数量

给定一个二维数组arr[]和值 K,其中arr[] 中的每个列表代表笛卡尔坐标上的一个点,任务是如果给定的点之间的距离小于或等于K,则将它们分组,并找出不相交的组的总数。

注意: 如果点'**a'**和'**b'**在同一组,'a','**d'**在同一组,那么'**b''d'**也在同一组。

例子。

**输入:**arr[] = {{73, -62}, {2, 2}, {3, 3}}, K = 1
输出。 3
**解释。**没有两个点的距离=1。
所以这三个点形成不同的不相交集。

**输入:**arr[] = {{3, 6}, {4, 2}, {3, 3}, {4, 9}}, K = 2
**输出。**3
**解释。**点{4, 2}和{3, 3}组成一个组。

使用Disjoint set union的方法。

解决这个问题的想法是基于以下的概念 不相交集联合.

假设所有的点都是一个不相交的组。所以,最初的不相交组的数量将是N (N是给定数组中的点的数量)。产生给定数组arr[] 中所有可能的点对**,** 然后检查它们之间的距离是否小于或等于K。如果满足条件,则将它们合并起来,并将不相交集的数量减少1。

按照下面的步骤来实现上述想法。

  • 创建一个大小为N 数组和等级数 组,其中N是给定数组中的点数,还有一个变量(例如cc) ,用于存储连接组件的数量,并通过N初始化cc
  • 将第i个点的父数组初始化为i(即parent[i] = i),rank[i] = 1。
  • 在给定的数组中生成所有可能的点对arr
  • 计算点之间的距离,检查它们之间的距离是否小于或等于 K
    • 如果距离小于等于k
      • 调用union1 函数来合并这些点。
      • 如果合并成功,则将cc 的计数减少1。
  • 最后,返回cc的数量。

下面是上述方法的实现。

C++

// C++ code to implement the approach

#include <bits/stdc++.h>
using namespace std;

// Function to find the parent of a node
int find(int x, vector<int>& parent)
{
	if (x == parent[x])
		return x;

	return parent[x] = find(parent[x], parent);
}

// Function to unite two sets
bool union1(int x, int y, vector<int>& parent,
			vector<int>& rank)
{
	int lx = find(x, parent);
	int ly = find(y, parent);

	// Condition of merging
	if (lx != ly) {
		if (rank[lx] > rank[ly]) {
			parent[ly] = lx;
		}
		else if (rank[lx] < rank[ly]) {
			parent[lx] = ly;
		}
		else {
			parent[lx] = ly;
			rank[ly] += 1;
		}

		// Return true for merging two
		// groups into one groups
		return true;
	}

	// Return false if points are
	// already merged.
	return false;
}

// Function to count the number of groups
// formed after grouping the points
int solve(vector<vector<int> >& points, int k)
{
	int n = points.size(),

		// cc is for number of
		// connected component
		cc = n;

	vector<int> parent(n), rank(n);

	for (int i = 0; i < n; i++) {
		parent[i] = i;
		rank[i] = 1;
	}

	// Iterate over all pairs of point
	for (int i = 0; i < n; i++) {
		for (int j = i + 1; j < n; j++) {

			double x1 = points[i][0], y1 = points[i][1];
			double x2 = points[j][0], y2 = points[j][1];

			// Calculate the distance
			// between the points
			double dist = (double)sqrt(pow(x2 - x1, 2)
									+ pow(y2 - y1, 2));

			// Check the given condition
			if (dist <= k) {

				// Merge this pair of points
				// into one group
				bool merge = union1(i, j, parent, rank);

				// If these points are getting
				// merged then reduce the cc by 1;
				if (merge)
					cc--;
			}
		}
	}

	return cc;
}

// Driver code
int main()
{
	vector<vector<int> > arr
		= { { 73, -62 }, { 2, 2 }, { 3, 3 } };
	int K = 1;
	int result = solve(arr, K);

	// Function Call
	cout << result << endl;
	return 0;
}

JAVA

// Java code to implement the approach
import java.io.*;

class GFG
{

// Function to find the parent of a node
public static int find(int x, int parent[])
{
	if (x == parent[x])
	return x;

	return parent[x] = find(parent[x], parent);
}

// Function to unite two sets
public static boolean union1(int x, int y, int parent[],
							int rank[])
{
	int lx = find(x, parent);
	int ly = find(y, parent);

	// Condition of merging
	if (lx != ly) {
	if (rank[lx] > rank[ly]) {
		parent[ly] = lx;
	}
	else if (rank[lx] < rank[ly]) {
		parent[lx] = ly;
	}
	else {
		parent[lx] = ly;
		rank[ly] += 1;
	}

	// Return true for merging two
	// groups into one groups
	return true;
	}

	// Return false if points are
	// already merged.
	return false;
}

// Function to count the number of groups
// formed after grouping the points
public static int solve(int points[][], int k)
{
	int n = points.length,

	// cc is for number of
	// connected component
	cc = n;

	int parent[] = new int[n];
	int rank[] = new int[n];

	for (int i = 0; i < n; i++) {
	parent[i] = i;
	rank[i] = 1;
	}

	// Iterate over all pairs of point
	for (int i = 0; i < n; i++) {
	for (int j = i + 1; j < n; j++) {

		double x1 = points[i][0], y1 = points[i][1];
		double x2 = points[j][0], y2 = points[j][1];

		// Calculate the distance
		// between the points
		double dist = (double)Math.sqrt(
		Math.pow(x2 - x1, 2)
		+ Math.pow(y2 - y1, 2));

		// Check the given condition
		if (dist <= k) {

		// Merge this pair of points
		// into one group
		boolean merge
			= union1(i, j, parent, rank);

		// If these points are getting
		// merged then reduce the cc by 1;
		if (merge == true)
			cc--;
		}
	}
	}

	return cc;
}

// Driver Code
public static void main(String[] args)
{
	int arr[][] = { { 73, -62 }, { 2, 2 }, { 3, 3 } };
	int K = 1;
	int result = solve(arr, K);

	// Function Call
	System.out.println(result);
}
}

// This code is contributed by Rohit Pradhan

Python3

import math

class GFG :

	# Function to find the parent of a node
	@staticmethod
	def find( x, parent) :
		if (x == parent[x]) :
			return x
		return
		parent[x] = GFG.find(parent[x], parent)
		
	# Function to unite two sets
	@staticmethod
	def union1( x, y, parent, rank) :
		lx = GFG.find(x, parent)
		ly = GFG.find(y, parent)
		
		# Condition of merging
		if (lx != ly) :
			if (rank[lx] > rank[ly]) :
				parent[ly] = lx
			elif(rank[lx] < rank[ly]) :
				parent[lx] = ly
			else :
				parent[lx] = ly
				rank[ly] += 1
				
			# Return true for merging two
			# groups into one groups
			return True
		
		# Return false if points are
		# already merged.
		return False
	
	# Function to count the number of groups
	# formed after grouping the points
	@staticmethod
	def solve( points, k) :
		n = len(points)
		cc = n
		parent = [0] * (n)
		rank = [0] * (n)
		i = 0
		while (i < n) :
			parent[i] = i
			rank[i] = 1
			i += 1
			
		# Iterate over all pairs of point
		i = 0
		while (i < n) :
			j = i + 1
			while (j < n) :
				x1 = points[i][0]
				y1 = points[i][1]
				x2 = points[j][0]
				y2 = points[j][1]
				
				# Calculate the distance
				# between the points
				dist = float(math.sqrt(math.pow(x2 - x1,2) + math.pow(y2 - y1,2)))
				
				# Check the given condition
				if (dist <= k) :
				
					# Merge this pair of points
					# into one group
					merge = GFG.union1(i, j, parent, rank)
					
					# If these points are getting
					# merged then reduce the cc by 1;
					if (merge == True) :
						cc -= 1
				j += 1
			i += 1
		return cc
	
	# Driver Code
	@staticmethod
	def main( args) :
		arr = [[73, -62], [2, 2], [3, 3]]
		K = 1
		result = GFG.solve(arr, K)
		
		# Function Call
		print(result)
	
if __name__=="__main__":
	GFG.main([])
	
	# This code is contributed by aadityaburujwale.

C#

// C# code to implement the approach
using System;
class GFG
{

	// Function to find the parent of a node
	static int find(int x, int[] parent)
	{
		if (x == parent[x])
			return x;

		return parent[x] = find(parent[x], parent);
	}

	// Function to unite two sets
	static bool union1(int x, int y, int[] parent,
					int[] rank)
	{
		int lx = find(x, parent);
		int ly = find(y, parent);

		// Condition of merging
		if (lx != ly) {
			if (rank[lx] > rank[ly]) {
				parent[ly] = lx;
			}
			else if (rank[lx] < rank[ly]) {
				parent[lx] = ly;
			}
			else {
				parent[lx] = ly;
				rank[ly] += 1;
			}

			// Return true for merging two
			// groups into one groups
			return true;
		}

		// Return false if points are
		// already merged.
		return false;
	}

	// Function to count the number of groups
	// formed after grouping the points
	static int solve(int[, ] points, int k, int n, int m)
	{

		// cc is for number of
		// connected component
		int cc = n;
		int[] parent = new int[n];
		int[] rank = new int[n];
		for (int i = 0; i < n; i++) {
			parent[i] = i;
			rank[i] = 1;
		}

		// Iterate over all pairs of point
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {

				double x1 = (double)points[i, 0],
					y1 = (double)points[i, 1];
				double x2 = (double)points[j, 0],
					y2 = (double)points[j, 1];

				// Calculate the distance
				// between the points
				double dist = (double)Math.Sqrt(
					Math.Pow(x2 - x1, 2)
					+ Math.Pow(y2 - y1, 2));

				// Check the given condition
				if (dist <= k) {

					// Merge this pair of points
					// into one group
					bool merge = union1(i, j, parent, rank);

					// If these points are getting
					// merged then reduce the cc by 1;
					if (merge)
						cc--;
				}
			}
		}

		return cc;
	}

	// Driver code
	public static void Main(string[] args)
	{

		int[, ] arr = new int[3, 2] { { 73, -62 },
									{ 2, 2 },
									{ 3, 3 } };
		int N = 3;
		int M = 2;
		int K = 1;
		int result = solve(arr, K, N, M);

		// Function Call
		Console.Write(result);
	}
}

// This code is contributed by garg28harsh.

Javascript

<script>
	// JavaScript code to implement the approach

	// Function to find the parent of a node
	const find = (x, parent) => {
		if (x == parent[x])
			return x;

		return parent[x] = find(parent[x], parent);
	}

	// Function to unite two sets
	const union1 = (x, y, parent, rank) => {
		let lx = find(x, parent);
		let ly = find(y, parent);

		// Condition of merging
		if (lx != ly) {
			if (rank[lx] > rank[ly]) {
				parent[ly] = lx;
			}
			else if (rank[lx] < rank[ly]) {
				parent[lx] = ly;
			}
			else {
				parent[lx] = ly;
				rank[ly] += 1;
			}

			// Return true for merging two
			// groups into one groups
			return true;
		}

		// Return false if points are
		// already merged.
		return false;
	}

	// Function to count the number of groups
	// formed after grouping the points
	const solve = (points, k) => {
		let n = points.length,

			// cc is for number of
			// connected component
			cc = n;

		let parent = new Array(n).fill(0), rank = new Array(n).fill(0);

		for (let i = 0; i < n; i++) {
			parent[i] = i;
			rank[i] = 1;
		}

		// Iterate over all pairs of point
		for (let i = 0; i < n; i++) {
			for (let j = i + 1; j < n; j++) {

				let x1 = points[i][0], y1 = points[i][1];
				let x2 = points[j][0], y2 = points[j][1];

				// Calculate the distance
				// between the points
				let dist = Math.sqrt(Math.pow(x2 - x1, 2)
					+ Math.pow(y2 - y1, 2));

				// Check the given condition
				if (dist <= k) {

					// Merge this pair of points
					// into one group
					let merge = union1(i, j, parent, rank);

					// If these points are getting
					// merged then reduce the cc by 1;
					if (merge)
						cc--;
				}
			}
		}

		return cc;
	}

	// Driver code
	let arr = [[73, -62], [2, 2], [3, 3]];
	let K = 1;
	let result = solve(arr, K);

	// Function Call
	document.write(result);

	// This code is contributed by rakeshsahni

</script>

输出

3

时间复杂度。O(N2),其中N是给定数组中的点的数量。
辅助空间。O(N),用于在UnionFind中存储父母和等级数组。