📜  从给定数组中找到一对相交的范围

📅  最后修改于: 2021-04-29 01:34:01             🧑  作者: Mango

给定大小为N * 2的2D数组range [] [] ,每行表示形式为[L,R]的范围,任务是找到两个范围,使第一个范围完全位于第二个范围内并打印他们的索引。如果无法获得这样的一对范围,请打印-1。如果存在多个这样的raneg,请打印其中任何一个。

例子:

天真的方法:解决问题的最简单方法是遍历数组,并针对每个范围遍历其余数组以检查是否存在完全位于当前范围内的范围,反之亦然。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效方法:为了优化上述方法,其思想是使用比较器函数对范围数组进行排序,并检查是否有任何段位于任何其他段之内。请按照下面给出的步骤解决此问题:

  • 按起点的升序对分段进行排序。在一对起点相等的情况下,以终点的降序排列。
  • 现在,遍历数组并保持如此获得的最大终点,并将其与当前段的终点进行比较。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Store ranges and their
// corresponding array indices
vector, int> > tup;
 
// Function to find a pair of intersecting ranges
void findIntersectingRange(int N, int ranges[][2])
{
 
    // Stores ending point
    // of every range
    int curr;
 
    // Stores the maximum
    // ending point obtained
    int currPos;
 
    // Iterate from 0 to N - 1
    for (int i = 0; i < N; i++) {
 
        int x, y;
 
        // Starting point of
        // the current range
        x = ranges[i][0];
 
        // End point of
        // the current range
        y = ranges[i][1];
 
        // Push pairs into tup
        tup.push_back({ { x, y }, i + 1 });
    }
 
    // Sort the tup vector
    sort(tup.begin(), tup.end());
 
    curr = tup[0].first.second;
    currPos = tup[0].second;
 
    // Iterate over the ranges
    for (int i = 1; i < N; i++) {
 
        int Q = tup[i - 1].first.first;
        int R = tup[i].first.first;
 
        // If starting points are equal
        if (Q == R) {
            if (tup[i - 1].first.second
                < tup[i].first.second)
                cout << tup[i - 1].second << ' '
                     << tup[i].second;
 
            else
                cout << tup[i].second << ' '
                     << tup[i - 1].second;
 
            return;
        }
 
        int T = tup[i].first.second;
 
        // Print the indices of the
        // intersecting ranges
        if (T <= curr) {
            cout << tup[i].second
                 << ' ' << currPos;
            return;
        }
        else {
            curr = T;
            currPos = tup[i].second;
        }
    }
 
    // If no such pair of segments exist
    cout << "-1 -1";
}
 
// Driver Code
int main()
{
    // Given N
    int N = 5;
 
    // Given 2d ranges[][] array
    int ranges[][2] = {
        { 1, 5 }, { 2, 10 },
        { 3, 10 }, { 2, 2 },
        { 2, 15 }};
 
    // Function call
    findIntersectingRange(N, ranges);
}


Java
// Java program for the above approach
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
 
class GFG{
 
// Store ranges and their
// corresponding array indices
static ArrayList tup = new ArrayList<>();
 
// Function to find a pair of intersecting ranges
static void findIntersectingRange(int N, int ranges[][])
{
     
    // Stores ending point
    // of every range
    int curr;
 
    // Stores the maximum
    // ending point obtained
    int currPos;
 
    // Iterate from 0 to N - 1
    for(int i = 0; i < N; i++)
    {
        int x, y;
 
        // Starting point of
        // the current range
        x = ranges[i][0];
 
        // End point of
        // the current range
        y = ranges[i][1];
 
        // Push pairs into tup
        int[] arr = { x, y, i + 1 };
        tup.add(arr);
    }
 
    // Sort the tup vector
    // sort(tup.begin(), tup.end());
    Collections.sort(tup, new Comparator()
    {
        public int compare(int[] a, int[] b)
        {
            if (a[0] == b[0])
            {
                if (a[1] == b[1])
                {
                    return a[2] - b[2];
                }
                else
                {
                    return a[1] - b[1];
                }
            }
            return a[0] - b[0];
        }
    });
 
    curr = tup.get(0)[1];
    currPos = tup.get(0)[2];
 
    // Iterate over the ranges
    for(int i = 1; i < N; i++)
    {
        int Q = tup.get(i - 1)[0];
        int R = tup.get(i)[0];
 
        // If starting points are equal
        if (Q == R)
        {
            if (tup.get(i - 1)[1] < tup.get(i)[1])
                System.out.print(tup.get(i - 1)[2] + " " +
                                 tup.get(i)[2]);
 
            else
                System.out.print(tup.get(i)[2] + " " +
                                 tup.get(i - 1)[2]);
            return;
        }
 
        int T = tup.get(i)[1];
 
        // Print the indices of the
        // intersecting ranges
        if (T <= curr)
        {
            System.out.print(tup.get(i)[2] + " " +
                             currPos);
            return;
        }
        else
        {
            curr = T;
            currPos = tup.get(i)[2];
        }
    }
 
    // If no such pair of segments exist
    System.out.print("-1 -1");
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given N
    int N = 5;
 
    // Given 2d ranges[][] array
    int ranges[][] = { { 1, 5 }, { 2, 10 },
                       { 3, 10 }, { 2, 2 },
                       { 2, 15 } };
 
    // Function call
    findIntersectingRange(N, ranges);
}
}
 
// This code is contributed by sanjeev2552


Python3
# Python3 program for the above approach
 
# Store ranges and their
# corresponding array indices
 
# Function to find a pair of intersecting ranges
def findIntersectingRange(tup, N, ranges):
 
    # Stores ending po
    # of every range
    curr = 0
 
    # Stores the maximum
    # ending poobtained
    currPos = 0
 
    # Iterate from 0 to N - 1
    for i in range(N):
 
        # Starting poof
        # the current range
        x = ranges[i][0]
 
        # End poof
        # the current range
        y = ranges[i][1]
 
        # Push pairs into tup
        tup.append([ [ x, y ], i + 1 ])
 
    # Sort the tup vector
    tup = sorted(tup)
 
    curr = tup[0][0][1]
    currPos = tup[0][1]
 
    # Iterate over the ranges
    for i in range(1, N):
 
        Q = tup[i - 1][0][0]
        R = tup[i][0][0]
 
        #If starting points are equal
        if (Q == R):
            if (tup[i - 1][0][1] < tup[i][0][1]):
                print(tup[i - 1][1], tup[i][1])
            else:
                print(tup[i][1], tup[i - 1][1])
            return
 
        T = tup[i][0][1]
 
        # Prthe indices of the
        # intersecting ranges
        if (T <= curr):
            print(tup[i][1], currPos)
            return
        else:
            curr = T
            currPos = tup[i][1]
 
    # If no such pair of segments exist
    print("-1 -1")
 
# Driver Code
if __name__ == '__main__':
    # Given N
    N = 5
 
    # Given 2d ranges[][] array
    ranges= [[ 1, 5 ], [ 2, 10 ],
            [ 3, 10 ], [ 2, 2 ],
            [ 2, 15 ]]
 
    # Function call
    findIntersectingRange([], N, ranges)
 
    # This code is contributed by mohit kumar 29


输出:
4 1

时间复杂度: O(N LogN)
辅助空间: O(N)