Given an array arr[] of distinct elements size N that is sorted and then rotated around an unknown point, the task is to check if the array has a pair with a given sum X.
Examples :
Input: arr[] = {11, 15, 6, 8, 9, 10}, X = 16
Output: true
Explanation: There is a pair (6, 10) with sum 16
Input: arr[] = {11, 15, 26, 38, 9, 10}, X = 35
Output: true
Explanation: There is a pair (26, 9) with sum 35
Input: arr[] = {11, 15, 26, 38, 9, 10}, X = 45
Output: false
Explanation: There is no pair with sum 45.
We have discussed an O(n) solution for a sorted array (See steps 2, 3, and 4 of Method 1) in this article. We can extend this solution for the rotated arrays as well.
Approach: The idea is:
First find the largest element in an array which is the pivot point also and the element just after the largest is the smallest element. Once we have the indices of the largest and the smallest elements, we use a similar meet-in-middle algorithm (as discussed here in method 1) to find if there is a pair.
The only thing new here is indices are incremented and decremented in a rotational manner using modular arithmetic.
Illustration:
Let us take an example arr[]={11, 15, 6, 8, 9, 10}, sum=16.
pivot = 1,
l = 2, r = 1:
=> arr[2] + arr[1] = 6 + 15 = 21 which is > 16
=> So decrement r circularly. r = ( 6 + 1 – 1) % 6, r = 0
l = 2, r = 0:
=> arr[2] + arr[0] = 17 which is > 16.
=> So decrement r circularly. r = (6 + 0 – 1) % 6, r = 5
l = 2, r = 5:
=> arr[2] + arr[5] = 16 which is equal to 16.
=> Hence return true
Hence there exists such a pair.
Follow the steps mentioned below to implement the idea:
- We will run a for loop from 0 to N-1, to find out the pivot point.
- Set the left pointer(l) to the smallest value and the right pointer(r) to the highest value.
- To restrict the circular movement within the array we will apply the modulo operation by the size of the array.
- While l ! = r, we shall keep checking if arr[l] + arr[r] = sum.
- If arr[l] + arr[r] is greater than X, update r = (N+r-1) % N.
- If arr[l] + arr[r] is less than X, update l = (l+1) % N.
- If arr[l] + arr[r] is equal to the value X, then return true.
- If no such pair is found after the iteration is complete, return false.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
bool pairInSortedRotated( int arr[], int n, int x)
{
int i;
for (i = 0; i < n - 1; i++)
if (arr[i] > arr[i + 1])
break ;
int l = (i + 1) % n;
int r = i;
while (l != r) {
if (arr[l] + arr[r] == x)
return true ;
if (arr[l] + arr[r] < x)
l = (l + 1) % n;
else
r = (n + r - 1) % n;
}
return false ;
}
int main()
{
int arr[] = { 11, 15, 6, 8, 9, 10 };
int X = 16;
int N = sizeof (arr) / sizeof (arr[0]);
if (pairInSortedRotated(arr, N, X))
cout << "true" ;
else
cout << "false" ;
return 0;
}
|
Java
import java.io.*;
class PairInSortedRotated {
static boolean pairInSortedRotated( int arr[], int n,
int x)
{
int i;
for (i = 0 ; i < n - 1 ; i++)
if (arr[i] > arr[i + 1 ])
break ;
int l = (i + 1 ) % n;
int r = i;
while (l != r) {
if (arr[l] + arr[r] == x)
return true ;
if (arr[l] + arr[r] < x)
l = (l + 1 ) % n;
else
r = (n + r - 1 ) % n;
}
return false ;
}
public static void main(String[] args)
{
int arr[] = { 11 , 15 , 6 , 8 , 9 , 10 };
int X = 16 ;
int N = arr.length;
if (pairInSortedRotated(arr, N, X))
System.out.print( "true" );
else
System.out.print( "false" );
}
}
|
Python3
def pairInSortedRotated(arr, n, x):
for i in range ( 0 , n - 1 ):
if (arr[i] > arr[i + 1 ]):
break
l = (i + 1 ) % n
r = i
while (l ! = r):
if (arr[l] + arr[r] = = x):
return True
if (arr[l] + arr[r] < x):
l = (l + 1 ) % n
else :
r = (n + r - 1 ) % n
return False
arr = [ 11 , 15 , 6 , 8 , 9 , 10 ]
X = 16
N = len (arr)
if (pairInSortedRotated(arr, N, X)):
print ( "true" )
else :
print ( "false" )
|
C#
using System;
class PairInSortedRotated {
static bool pairInSortedRotated( int [] arr, int n, int x)
{
int i;
for (i = 0; i < n - 1; i++)
if (arr[i] > arr[i + 1])
break ;
int l = (i + 1) % n;
int r = i;
while (l != r) {
if (arr[l] + arr[r] == x)
return true ;
if (arr[l] + arr[r] < x)
l = (l + 1) % n;
else
r = (n + r - 1) % n;
}
return false ;
}
public static void Main()
{
int [] arr = { 11, 15, 6, 8, 9, 10 };
int X = 16;
int N = arr.Length;
if (pairInSortedRotated(arr, N, X))
Console.WriteLine( "true" );
else
Console.WriteLine( "false" );
}
}
|
PHP
<?php
function pairInSortedRotated( $arr , $n , $x )
{
$i ;
for ( $i = 0; $i < $n - 1; $i ++)
if ( $arr [ $i ] > $arr [ $i + 1])
break ;
$l = ( $i + 1) % $n ;
$r = $i ;
while ( $l != $r )
{
if ( $arr [ $l ] + $arr [ $r ] == $x )
return true;
if ( $arr [ $l ] + $arr [ $r ] < $x )
$l = ( $l + 1) % $n ;
else
$r = ( $n + $r - 1) % $n ;
}
return false;
}
$arr = array (11, 15, 6, 8, 9, 10);
$X = 16;
$N = sizeof( $arr );
if (pairInSortedRotated( $arr , $N , $X ))
echo "true" ;
else
echo "false" ;
?>
|
Javascript
<script>
function pairInSortedRotated(arr, n, x)
{
let i;
for (i = 0; i < n - 1; i++)
if (arr[i] > arr[i + 1])
break ;
let l = (i + 1) % n;
let r = i;
while (l != r)
{
if (arr[l] + arr[r] == x)
return true ;
if (arr[l] + arr[r] < x)
l = (l + 1) % n;
else
r = (n + r - 1) % n;
}
return false ;
}
let arr = [ 11, 15, 6, 8, 9, 10 ];
let X = 16;
let N = arr.length;
if (pairInSortedRotated(arr, N, X))
document.write( "true" );
else
document.write( "false" );
</script>
|
Time Complexity: O(N). The step to find the pivot can be optimized to O(Logn) using the Binary Search approach discussed here.
Auxiliary Space: O(1).
Exercise:
1) Extend the above solution to work for arrays with duplicates allowed.
This article is contributed by Himanshu Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Approach#2: Using two pointers and binary search
The approach finds the pivot element in the rotated sorted array and then uses two pointers to check if there is a pair with a given sum. The pointers move in a circular way using the modulo operator.
Algorithm
1. Find the pivot element in the rotated sorted array. If the pivot element is greater than the first element of the array, then the pivot lies in the second half of the array; otherwise, it lies in the first half of the array.
2. After finding the pivot element, initialize two pointers left and right at the start and end of the array, respectively.
3. Loop through the array and check if the sum of the elements at the left and right pointers is equal to the given sum. If it is, then return true.
4. If the sum is less than the given sum, increment the left pointer, else decrement the right pointer.
5. If the loop completes and no pair is found, return false.
C++
#include <iostream>
using namespace std;
bool findPair( int arr[], int n, int x)
{
int pivot = 0;
for ( int i = 0; i < n - 1; i++) {
if (arr[i] > arr[i + 1]) {
pivot = i + 1;
break ;
}
}
int left = pivot;
int right = pivot - 1;
while (left != right) {
if (arr[left] + arr[right] == x) {
return true ;
}
else if (arr[left] + arr[right] < x) {
left = (left + 1) % n;
}
else {
right = (right - 1 + n) % n;
}
}
return false ;
}
int main()
{
int arr[] = { 11, 15, 6, 8, 9, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
int x = 16;
cout << boolalpha << findPair(arr, n, x);
return 0;
}
|
Java
public class FindPairInRotatedArray {
public static boolean findPair( int [] arr, int x) {
int n = arr.length;
int pivot = 0 ;
for ( int i = 0 ; i < n- 1 ; i++) {
if (arr[i] > arr[i+ 1 ]) {
pivot = i+ 1 ;
break ;
}
}
int left = pivot;
int right = pivot- 1 ;
while (left != right) {
if (arr[left] + arr[right] == x) {
return true ;
}
else if (arr[left] + arr[right] < x) {
left = (left+ 1 ) % n;
}
else {
right = (right- 1 +n) % n;
}
}
return false ;
}
public static void main(String[] args) {
int [] arr = { 11 , 15 , 6 , 8 , 9 , 10 };
int x = 16 ;
System.out.println(findPair(arr, x));
}
}
|
Python3
def find_pair(arr, x):
n = len (arr)
pivot = 0
for i in range (n - 1 ):
if arr[i] > arr[i + 1 ]:
pivot = i + 1
break
left = pivot
right = pivot - 1
while left ! = right:
if arr[left] + arr[right] = = x:
return True
elif arr[left] + arr[right] < x:
left = (left + 1 ) % n
else :
right = (right - 1 + n) % n
return False
arr = [ 11 , 15 , 6 , 8 , 9 , 10 ]
x = 16
print (find_pair(arr, x))
|
C#
using System;
public class FindPairInRotatedArray {
public static bool FindPair( int [] arr, int x) {
int n = arr.Length;
int pivot = 0;
for ( int i = 0; i < n-1; i++) {
if (arr[i] > arr[i+1]) {
pivot = i+1;
break ;
}
}
int left = pivot;
int right = pivot-1;
while (left != right) {
if (arr[left] + arr[right] == x) {
return true ;
}
else if (arr[left] + arr[right] < x) {
left = (left+1) % n;
}
else {
right = (right-1+n) % n;
}
}
return false ;
}
public static void Main( string [] args) {
int [] arr = {11, 15, 6, 8, 9, 10};
int x = 16;
Console.WriteLine(FindPair(arr, x));
}
}
|
Javascript
function findPair(arr, x) {
const n = arr.length;
let pivot = 0;
for (let i = 0; i < n - 1; i++) {
if (arr[i] > arr[i + 1]) {
pivot = i + 1;
break ;
}
}
let left = pivot;
let right = pivot - 1;
while (left !== right) {
if (arr[left] + arr[right] === x) {
return true ;
} else if (arr[left] + arr[right] < x) {
left = (left + 1) % n;
} else {
right = (right - 1 + n) % n;
}
}
return false ;
}
const arr = [11, 15, 6, 8, 9, 10];
const x = 16;
console.log(findPair(arr, x));
|
Time Complexity: O(n), where n is the length of the input array.
Space Complexity: O(1).