在 O(NlogN) 中的所有子数组上查找所有唯一的最大和第二最大元素对
让分别表示数组的第二个最大值和最大元素的有序对。我们需要在给定数组的整个连续子数组中找到所有这些唯一对。
例子:
Input: Arr = [ 1, 2, 3, 4, 5 ]
Output: (1, 2) (2, 3) (3, 4) (4, 5)
Input: Arr = [ 1, 1, 2 ]
Output: (1, 1) (1, 2)
Input: Arr = [ 1, 2, 6, 4, 5 ]
Output: (1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
蛮力方法:
- 解决此问题的一种简单方法是扫描每个子数组并找到该子数组中的最大和第二大元素
- 这可以在时间
- 然后我们可以将每一对插入一个集合中以确保删除重复项,然后打印它们
- 每次插入操作成本 ,将最终的复杂度推到
C++14
// C++ implementation
#include
using namespace std;
// Function to return the set of pairs
set > pairs(vector& arr)
{
set > pairs;
// find all subarrays
for (int i = 0; i < arr.size() - 1; ++i) {
int maximum = max(arr[i], arr[i + 1]),
secondmax = min(arr[i], arr[i + 1]);
for (int j = i + 1; j < arr.size(); ++j) {
// update max and second max
if (arr[j] > maximum) {
secondmax = maximum;
maximum = arr[j];
}
if (arr[j] < maximum && arr[j] > secondmax) {
secondmax = arr[j];
}
// insert a pair in set
pairs.insert(make_pair(secondmax, maximum));
}
}
return pairs;
}
int main()
{
vector vec = { 1, 2, 6, 4, 5 };
set > st = pairs(vec);
cout << "Total Number of valid pairs is :"
<< (int)st.size() << "\n";
for (auto& x : st) {
cout << "(" << x.first << ", " << x.second << ") ";
}
return 0;
}
Java
// Java implementation
import java.util.HashSet;
import java.util.Set;
class Pair implements Comparable {
int first, second;
public Pair(int first, int second)
{
this.first = first;
this.second = second;
}
@Override public int hashCode()
{
return 31 * first + second;
}
public boolean equals(Object p)
{
Pair pair = (Pair)p;
if (this.first != pair.first)
return false;
return this.second == pair.second;
}
@Override public int compareTo(Pair p)
{
if (this.first == p.first) {
return this.second - p.second;
}
return this.first - p.first;
}
}
class GFG {
// Function to return the set of pairs
static Set pairs(int[] arr)
{
Set pairs = new HashSet<>();
// Find all subarrays
for (int i = 0; i < arr.length - 1; ++i) {
int maximum = Math.max(arr[i], arr[i + 1]),
secondmax = Math.min(arr[i], arr[i + 1]);
for (int j = i + 1; j < arr.length; ++j) {
// Update max and second max
if (arr[j] > maximum) {
secondmax = maximum;
maximum = arr[j];
}
if (arr[j] < maximum
&& arr[j] > secondmax) {
secondmax = arr[j];
}
// Insert a pair in set
pairs.add(new Pair(secondmax, maximum));
}
}
return pairs;
}
// Driver Code
public static void main(String[] args)
{
int[] vec = { 1, 2, 6, 4, 5 };
Set st = pairs(vec);
System.out.println("Total Number of "
+ "valid pairs is :"
+ st.size());
for (Pair x : st) {
System.out.printf("(%d, %d)\n", x.first,
x.second);
}
}
}
// This code is contributed by sanjeev2552
Python3
# python3 implementation
# Function to return the set of pairs
def SetofPairs(arr):
pairs = set()
n = len(arr) # length of array
# find all subarrays
for i in range(n - 1):
maximum = max(arr[i], arr[i + 1])
secondmax = min(arr[i], arr[i + 1])
for j in range(i + 1, n):
# update max and second max
if (arr[j] > maximum):
secondmax = maximum
maximum = arr[j]
if (arr[j] < maximum and arr[j] > secondmax):
secondmax = arr[j]
# add a pair in set
pairs.add((secondmax, maximum))
return pairs
# Driver code
if __name__ == "__main__":
vec = [1, 2, 6, 4, 5]
st = SetofPairs(vec)
print("Total Number of valid pairs is :", len(st))
for x in st:
print(x, end = " ")
# This code is contributed by sunilsoni10220001022000.
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to return the set of pairs
set>
pairs(vector& arr)
{
stack st;
set> pairs;
// Push first element into stack
st.push(arr[0]);
// For each element 'X' in arr,
// pop the stack while top Element
// is smaller than 'X' and form a pair.
// If the stack is not empty after
// the previous operation, create
// a pair. Push X into the stack.
for (int i = 1; i < arr.size(); ++i) {
while (!st.empty() &&
arr[i] > st.top()) {
pairs.insert(make_pair(st.top(),
arr[i]));
st.pop();
}
if (!st.empty()) {
pairs.insert(make_pair(min(st.top(),
arr[i]),
max(st.top(),
arr[i])));
}
st.push(arr[i]);
}
return pairs;
}
int main()
{
vector vec = { 1, 2, 6, 4, 5 };
set > st = pairs(vec);
cout << "Total Number of valid pairs is :"
<< (int)st.size() << "\n";
for (auto& x : st) {
cout << "(" << x.first << ", "
<< x.second << ") ";
}
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + first;
result = prime * result + second;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
pair other = (pair) obj;
if (first != other.first)
return false;
if (second != other.second)
return false;
return true;
}
}
// Function to return the set of pairs
static HashSet pairs(int[] arr)
{
Stack st = new Stack();
HashSet pairs = new HashSet();
// Push first element into stack
st.add(arr[0]);
// For each element 'X' in arr,
// pop the stack while top Element
// is smaller than 'X' and form a pair.
// If the stack is not empty after
// the previous operation, create
// a pair. Push X into the stack.
for(int i = 1; i < arr.length; ++i)
{
while (!st.isEmpty() && arr[i] > st.peek())
{
pairs.add(new pair(st.peek(),
arr[i]));
st.pop();
}
if (!st.isEmpty())
{
pairs.add(new pair(Math.min(st.peek(),
arr[i]),
Math.max(st.peek(),
arr[i])));
}
st.add(arr[i]);
}
return pairs;
}
// Driver code
public static void main(String[] args)
{
int [] vec = { 1, 2, 6, 4, 5 };
HashSet st = pairs(vec);
System.out.print("Total Number of valid pairs is :" +
(int)st.size() + "\n");
for(pair x : st)
{
System.out.print("(" + x.first+ ", " +
x.second + ") ");
}
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the above approach
# Function to return the set of pairs
def pairs(arr) :
st = [];
pairs = [];
# Push first element into stack
st.append(arr[0]);
# For each element 'X' in arr,
# pop the stack while top Element
# is smaller than 'X' and form a pair.
# If the stack is not empty after
# the previous operation, create
# a pair. Push X into the stack.
for i in range(1, len(arr) ) :
while len(st) != 0 and arr[i] > st[-1] :
pairs.append((st[-1], arr[i]));
st.pop();
if len(st) != 0 :
pairs.append((min(st[-1], arr[i]),
max(st[-1], arr[i])));
st.append(arr[i]);
return pairs;
# Driver code
if __name__ == "__main__" :
vec = [ 1, 2, 6, 4, 5 ];
st = pairs(vec);
print("Total Number of valid pairs is :",len(st));
for x in st :
print("(" ,x[0], ", ",x[1], ")",end=" ");
# This code is contributed by AnkitRai01
输出:
Total Number of valid pairs is :5
(1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
复杂性分析:
- 时间复杂度: O(N^2 log(N))。
在集合中插入需要 log N 时间。最多可以有 N^2 个子数组。所以时间复杂度是 O(N^2 log N)。 - 辅助空间: O(n^2)。
因为需要额外的空间来存储集合中的元素。
有效的方法:
- 它可以降低寻找配对的复杂性通过观察一个元素只能与元素形成对,直到最右边的元素大于 .
- 要了解为什么会这样,请考虑 = 在下一个示例中。
Arr = {1, 4, 5, 3, 2, 1}
- 它可以看到是离右边最近的大于 . 考虑子阵列形成一对 .
- 其他子数组,以必须包括 .考虑其中一个,如果另一个元素存在于子数组中,则将是该子阵列的对。
- 否则将形成或将形成,其中是右边的最大元素在子阵中。
- 在任何情况下, 不能与右边的任何元素形成对 .
- 使用这个观察,我们可以使用堆栈来实现逻辑,这将生成对的复杂度降低到 .
- 每对都可以插入到一个集合中以消除重复,最终的时间复杂度为
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to return the set of pairs
set>
pairs(vector& arr)
{
stack st;
set> pairs;
// Push first element into stack
st.push(arr[0]);
// For each element 'X' in arr,
// pop the stack while top Element
// is smaller than 'X' and form a pair.
// If the stack is not empty after
// the previous operation, create
// a pair. Push X into the stack.
for (int i = 1; i < arr.size(); ++i) {
while (!st.empty() &&
arr[i] > st.top()) {
pairs.insert(make_pair(st.top(),
arr[i]));
st.pop();
}
if (!st.empty()) {
pairs.insert(make_pair(min(st.top(),
arr[i]),
max(st.top(),
arr[i])));
}
st.push(arr[i]);
}
return pairs;
}
int main()
{
vector vec = { 1, 2, 6, 4, 5 };
set > st = pairs(vec);
cout << "Total Number of valid pairs is :"
<< (int)st.size() << "\n";
for (auto& x : st) {
cout << "(" << x.first << ", "
<< x.second << ") ";
}
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + first;
result = prime * result + second;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
pair other = (pair) obj;
if (first != other.first)
return false;
if (second != other.second)
return false;
return true;
}
}
// Function to return the set of pairs
static HashSet pairs(int[] arr)
{
Stack st = new Stack();
HashSet pairs = new HashSet();
// Push first element into stack
st.add(arr[0]);
// For each element 'X' in arr,
// pop the stack while top Element
// is smaller than 'X' and form a pair.
// If the stack is not empty after
// the previous operation, create
// a pair. Push X into the stack.
for(int i = 1; i < arr.length; ++i)
{
while (!st.isEmpty() && arr[i] > st.peek())
{
pairs.add(new pair(st.peek(),
arr[i]));
st.pop();
}
if (!st.isEmpty())
{
pairs.add(new pair(Math.min(st.peek(),
arr[i]),
Math.max(st.peek(),
arr[i])));
}
st.add(arr[i]);
}
return pairs;
}
// Driver code
public static void main(String[] args)
{
int [] vec = { 1, 2, 6, 4, 5 };
HashSet st = pairs(vec);
System.out.print("Total Number of valid pairs is :" +
(int)st.size() + "\n");
for(pair x : st)
{
System.out.print("(" + x.first+ ", " +
x.second + ") ");
}
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the above approach
# Function to return the set of pairs
def pairs(arr) :
st = [];
pairs = [];
# Push first element into stack
st.append(arr[0]);
# For each element 'X' in arr,
# pop the stack while top Element
# is smaller than 'X' and form a pair.
# If the stack is not empty after
# the previous operation, create
# a pair. Push X into the stack.
for i in range(1, len(arr) ) :
while len(st) != 0 and arr[i] > st[-1] :
pairs.append((st[-1], arr[i]));
st.pop();
if len(st) != 0 :
pairs.append((min(st[-1], arr[i]),
max(st[-1], arr[i])));
st.append(arr[i]);
return pairs;
# Driver code
if __name__ == "__main__" :
vec = [ 1, 2, 6, 4, 5 ];
st = pairs(vec);
print("Total Number of valid pairs is :",len(st));
for x in st :
print("(" ,x[0], ", ",x[1], ")",end=" ");
# This code is contributed by AnkitRai01
输出:
Total Number of valid pairs is :5
(1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
复杂性分析:
- 时间复杂度: O(N log(N))。
每对都可以插入到一个集合中以消除重复,最终时间复杂度为 O(N log N) - 辅助空间: O(N)。
因为需要额外的空间来存储集合中的元素。