在给定范围的合并和排序列表中查找第 N 个数字
给定两个整数数组L和R以及一个整数N 。给定数组中的每个范围表示存在范围[L[i], R[i]]中的每个数字。任务是在给定范围内的数字按其排序顺序排序时计算第N 个(基于 0 的索引)元素。
例子:
Input: L = {1, 5}, R = {3, 7}, N = 4
Output: 6
Explanation: The numbers present are {1, 2, 3, 5, 6, 7}. Therefore 4-th element(0-indexed) is 6.
Input: L = {1, 3}, R = {4, 5}, N = 3
Output: 3
Explanation: The numbers present are {1, 2, 3, 4, 3, 4, 5} and their sorted order is {1, 2, 3, 3, 4, 4, 5}. Therefore 3-rd element(0-indexed) is 3.
方法:可以通过对答案进行二分搜索来解决该任务。
请按照以下步骤解决问题:
- 计算两个变量min和max ,它们存储L数组中的最小元素和R数组中的最大元素。
- 二分查找的范围是[min, max] 。
- 对于每个mid = (min + max) / 2计算当前元素的位置。
- 要计算位置,请遍历所有范围并设置变量 t = 0 来存储位置。如果L[i] >= mid ,请检查以下两个条件
- 如果mid <= R[i] ,更新 t += mid – L[i] + 1。
- 否则 t += R[i] – L[i] + 1
- 二分搜索范围可以更新为
- 如果(t > n)最大 =中 - 1。
- 否则 min = mid + 1 。
- 最终答案将存储在变量min中。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
int nthElement(vector L, vector R, int n)
{
// Store the size of the ranges
int K = L.size();
// Calculate the max and min values
long long min = 2000000000, max = -2000000000;
for (int i = 0; i < K; i++) {
if (L[i] < min)
min = L[i];
if (R[i] > max)
max = R[i];
}
// Do a binary search over answer
while (min <= max) {
long long mid = (min + max) / 2;
long long t = 0;
for (int i = 0; i < K; i++) {
if (mid >= L[i]) {
if (mid <= R[i]) {
t += mid - L[i] + 1;
}
else {
t += R[i] - L[i] + 1;
}
}
}
// Update the binary Search range.
if (t > n) {
max = mid - 1;
}
else {
min = mid + 1;
}
}
return min;
}
// Driver Code
int main()
{
vector L = { 1, 5 }, R = { 3, 7 };
int N = 4;
cout << nthElement(L, R, N);
}
Java
// Java implementation for the above approach
class GFG {
public static long nthElement(int[] L, int[] R, int n) {
// Store the size of the ranges
int K = L.length;
// Calculate the max and min values
long min = 2000000000, max = -2000000000;
for (int i = 0; i < K; i++) {
if (L[i] < min)
min = L[i];
if (R[i] > max)
max = R[i];
}
// Do a binary search over answer
while (min <= max) {
long mid = (min + max) / 2;
long t = 0;
for (int i = 0; i < K; i++) {
if (mid >= L[i]) {
if (mid <= R[i]) {
t += mid - L[i] + 1;
} else {
t += R[i] - L[i] + 1;
}
}
}
// Update the binary Search range.
if (t > n) {
max = mid - 1;
} else {
min = mid + 1;
}
}
return min;
}
// Driver Code
public static void main(String args[]) {
int[] L = { 1, 5 }, R = { 3, 7 };
int N = 4;
System.out.println(nthElement(L, R, N));
}
}
// This code is contributed by gfgking
Python3
# Python implementation for the above approach
def nthElement(L, R, n):
# Store the size of the ranges
K = len(L)
# Calculate the max and min values
min = 2000000000
max = -2000000000;
for i in range(K):
if (L[i] < min):
min = L[i]
if (R[i] > max):
max = R[i];
# Do a binary search over answer
while (min <= max):
mid = (min + max) // 2;
t = 0;
for i in range(K):
if (mid >= L[i]):
if (mid <= R[i]):
t += mid - L[i] + 1;
else:
t += R[i] - L[i] + 1;
# Update the binary Search range.
if (t > n):
max = mid - 1;
else:
min = mid + 1;
return min;
# Driver Code
L = [1, 5]
R = [3, 7];
N = 4;
print(nthElement(L, R, N));
# This code is contributed by gfgking
C#
// C# implementation for the above approach
using System;
class GFG {
public static long nthElement(int[] L, int[] R, int n)
{
// Store the size of the ranges
int K = L.Length;
// Calculate the max and min values
long min = 2000000000, max = -2000000000;
for (int i = 0; i < K; i++) {
if (L[i] < min)
min = L[i];
if (R[i] > max)
max = R[i];
}
// Do a binary search over answer
while (min <= max) {
long mid = (min + max) / 2;
long t = 0;
for (int i = 0; i < K; i++) {
if (mid >= L[i]) {
if (mid <= R[i]) {
t += mid - L[i] + 1;
} else {
t += R[i] - L[i] + 1;
}
}
}
// Update the binary Search range.
if (t > n) {
max = mid - 1;
} else {
min = mid + 1;
}
}
return min;
}
// Driver Code
public static void Main() {
int[] L = { 1, 5 }, R = { 3, 7 };
int N = 4;
Console.Write(nthElement(L, R, N));
}
}
// This code is contributed by gfgking
Javascript
输出
6
时间复杂度:O(N*log(max – min))
辅助空间: O(N)