Open In App

C++ Program for Given a sorted and rotated array, find if there is a pair with a given sum

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array that is sorted and then rotated around an unknown point. Find if the array has a pair with a given sum ‘x’. It may be assumed that all elements in the array are distinct.

Examples : 

Input: arr[] = {11, 15, 6, 8, 9, 10}, x = 16
Output: true
There is a pair (6, 10) with sum 16

Input: arr[] = {11, 15, 26, 38, 9, 10}, x = 35
Output: true
There is a pair (26, 9) with sum 35

Input: arr[] = {11, 15, 26, 38, 9, 10}, x = 45
Output: false
There is no pair with sum 45.

We have discussed a O(n) solution for a sorted array (See steps 2, 3 and 4 of Method 1). We can extend this solution for rotated array as well. The idea is to first find the largest element in array which is the pivot point also and the element just after largest is the smallest element. Once we have indexes largest and smallest elements, we use similar meet in middle algorithm (as discussed here in method 1) to find if there is a pair. The only thing new here is indexes are incremented and decremented in rotational manner using modular arithmetic.

Following is the implementation of above idea.  

Output : 

Array has two elements with sum 16

The time complexity of the above solution is O(n). The step to find the pivot can be optimized to O(Logn) using the Binary Search approach discussed here.

Space Complexity:  O(1) as no extra space has been used.

How to count all pairs having sum x? 
The stepwise algo is:  

  1. Find the pivot element of the sorted and the rotated array. The pivot element is the largest element in the array. The smallest element will be adjacent to it.
  2. Use two pointers (say left and right) with the left pointer pointing to the smallest element and the right pointer pointing to largest element.
  3. Find the sum of the elements pointed by both the pointers.
  4. If the sum is equal to x, then increment the count. If the sum is less than x, then to increase sum move the left pointer to next position by incrementing it in a rotational manner. If the sum is greater than x, then to decrease sum move the right pointer to next position by decrementing it in rotational manner.
  5. Repeat step 3 and 4 until the left pointer is not equal to the right pointer or until the left pointer is not equal to right pointer – 1.
  6. Print final count.

Below is implementation of above algorithm: 

C++




// C++ program to find number of pairs with
// a given sum in a sorted and rotated array.
#include<bits/stdc++.h>
using namespace std;
 
// This function returns count of number of pairs
// with sum equals to x.
int pairsInSortedRotated(int arr[], int n, int x)
{
    // Find the pivot element. Pivot element
    // is largest element of array.
    int i;
    for (i = 0; i < n-1; i++)
        if (arr[i] > arr[i+1])
            break;
     
    // l is index of smallest element.
    int l = (i + 1) % n;
     
    // r is index of largest element.
    int r = i;
     
    // Variable to store count of number
    // of pairs.
    int cnt = 0;
 
    // Find sum of pair formed by arr[l] and
    // and arr[r] and update l, r and cnt
    // accordingly.
    while (l != r)
    {
        // If we find a pair with sum x, then
        // increment cnt, move l and r to
        // next element.
        if (arr[l] + arr[r] == x){
            cnt++;
             
            // This condition is required to
            // be checked, otherwise l and r
            // will cross each other and loop
            // will never terminate.
            if(l == (r - 1 + n) % n){
                return cnt;
            }
             
            l = (l + 1) % n;
            r = (r - 1 + n) % n;
        }
 
        // If current pair sum is less, move to
        // the higher sum side.
        else if (arr[l] + arr[r] < x)
            l = (l + 1) % n;
         
        // If current pair sum is greater, move
        // to the lower sum side.
        else
            r = (n + r - 1)%n;
    }
     
    return cnt;
}
 
/* Driver program to test above function */
int main()
{
    int arr[] = {11, 15, 6, 7, 9, 10};
    int sum = 16;
    int n = sizeof(arr)/sizeof(arr[0]);
 
    cout << pairsInSortedRotated(arr, n, sum);
     
    return 0;
}


Output: 

2

Time Complexity: O(n) 
Auxiliary Space: O(1) 
This method is suggested by Nikhil Jindal.
 

Exercise: 
1) Extend the above solution to work for arrays with duplicates allowed.

Method:  Two-pointer approach

  1. Find the pivot element of the rotated sorted array using a modified binary search algorithm.
  2. Initialize two pointers, one pointing to the smallest element of the array and the other pointing to the largest element of the array.
  3. While the left pointer is less than the right pointer, repeat steps 4 to 6.
  4. Compute the sum of the elements pointed by the left and right pointers.
  5. If the sum is equal to the given sum, return true.
  6. If the sum is greater than the given sum, decrement the right pointer. If the sum is less than the given sum, increment the left pointer.
  7. If no pair with the given sum is found, return false. 

C++




#include <iostream>
using namespace std;
 
bool pairInSortedRotated(int arr[], int n, int x)
{
    // Find the pivot element using binary search
    int i;
    for (i = 0; i < n - 1; i++)
        if (arr[i] > arr[i + 1])
            break;
 
    // Initialize left and right pointers
    int left = (i + 1) % n;
    int right = i;
 
    // Find the pair with the given sum
    while (left != right)
    {
        // If we find a pair with the given sum, return true
        if (arr[left] + arr[right] == x)
            return true;
 
        // If the sum is greater than the given sum, decrement the right pointer
        else if (arr[left] + arr[right] > x)
            right = (n + right - 1) % n;
 
        // If the sum is less than the given sum, increment the left pointer
        else
            left = (left + 1) % n;
    }
 
    // If no pair with the given sum is found, return false
    return false;
}
 
int main()
{
    int arr1[] = {11, 15, 6, 8, 9, 10};
    int n1 = sizeof(arr1) / sizeof(arr1[0]);
    int x1 = 16;
 
    if (pairInSortedRotated(arr1, n1, x1))
        cout << "True";
    else
        cout << "False";
 
    cout << endl;
 
    int arr2[] = {11, 15, 26, 38, 9, 10};
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    int x2 = 35;
 
    if (pairInSortedRotated(arr2, n2, x2))
        cout << "True";
    else
        cout << "False";
 
    cout << endl;
 
    int arr3[] = {11, 15, 26, 38, 9, 10};
    int n3 = sizeof(arr3) / sizeof(arr3[0]);
    int x3 = 45;
 
    if (pairInSortedRotated(arr3, n3, x3))
        cout << "True";
    else
        cout << "False";
 
    return 0;
}


Output

True
True
False

Time complexity: O(n) 
Auxiliary space: O(1)

Please refer complete article on Given a sorted and rotated array, find if there is a pair with a given sum for more details!



Last Updated : 03 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads