📌  相关文章
📜  给定一个排序和旋转数组的Java程序,查找是否存在具有给定总和的对

📅  最后修改于: 2022-05-13 01:55:31.325000             🧑  作者: Mango

给定一个排序和旋转数组的Java程序,查找是否存在具有给定总和的对

给定一个经过排序然后围绕未知点旋转的数组。查找数组是否具有给定总和“x”的对。可以假设数组中的所有元素都是不同的。

例子 :

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.

我们已经讨论了排序数组的 O(n) 解决方案(参见方法 1 的步骤 2、3 和 4)。我们也可以将此解决方案扩展到旋转数组。这个想法是首先在数组中找到最大的元素,它也是枢轴点,最大之后的元素是最小的元素。一旦我们有索引最大和最小的元素,我们使用类似的中间算法(如方法 1 中讨论的这里)来查找是否存在一对。这里唯一新的是索引使用模运算以旋转方式递增和递减。

以下是上述思想的实现。

Java
// Java program to find a pair with a given 
// sum in a sorted and rotated array
class PairInSortedRotated
{
    // This function returns true if arr[0..n-1] 
    // has a pair with sum equals to x.
    static boolean pairInSortedRotated(int arr[], 
                                    int n, int x)
    {
        // Find the pivot element
        int i;
        for (i = 0; i < n - 1; i++)
            if (arr[i] > arr[i+1])
                break;
                  
        int l = (i + 1) % n; // l is now index of                                          
                            // smallest element
                           
        int r = i;       // r is now index of largest 
                         //element
       
        // Keep moving either l or r till they meet
        while (l != r)
        {
             // If we find a pair with sum x, we
             // return true
             if (arr[l] + arr[r] == x)
                  return true;
       
             // If current pair sum is less, move 
             // to the higher sum
             if (arr[l] + arr[r] < x)
                  l = (l + 1) % n;
                    
             else  // Move to the lower sum side
                  r = (n + r - 1) % n;
        }
        return false;
    }
  
    /* Driver program to test above function */
    public static void main (String[] args)
    {
        int arr[] = {11, 15, 6, 8, 9, 10};
        int sum = 16;
        int n = arr.length;
       
        if (pairInSortedRotated(arr, n, sum))
            System.out.print("Array has two elements" +
                             " with sum 16");
        else
            System.out.print("Array doesn't have two" + 
                             " elements with sum 16 ");
    }
}
/*This code is contributed by Prakriti Gupta*/


Java
// Java program to find 
// number of pairs with 
// a given sum in a sorted 
// and rotated array.
import java.io.*;
  
class GFG
{
      
// This function returns
// count of number of pairs
// with sum equals to x.
static 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 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 Code
public static void main (String[] args) 
{
    int arr[] = {11, 15, 6, 7, 9, 10};
    int sum = 16;
    int n = arr.length;
  
    System.out.println(
            pairsInSortedRotated(arr, n, sum));
}
}
  
// This code is contributed by ajit


输出 :

Array has two elements with sum 16

上述解决方案的时间复杂度为 O(n)。使用此处讨论的二分搜索方法,可以将找到枢轴的步骤优化为 O(Logn)。

如何计算总和为x的所有对?
逐步算法是:

  1. 找到已排序和旋转数组的枢轴元素。枢轴元素是数组中最大的元素。最小的元素将与其相邻。
  2. 使用两个指针(比如左和右),左指针指向最小元素,右指针指向最大元素。
  3. 求两个指针所指向的元素之和。
  4. 如果总和等于 x,则增加计数。如果总和小于 x,则通过以旋转方式递增左指针来增加总和,将左指针移动到下一个位置。如果总和大于 x,则通过以旋转方式递减右指针来减少总和,将右指针移动到下一个位置。
  5. 重复步骤 3 和 4,直到左指针不等于右指针或直到左指针不等于右指针 - 1。
  6. 打印最终计数。

下面是上述算法的实现:

Java

// Java program to find 
// number of pairs with 
// a given sum in a sorted 
// and rotated array.
import java.io.*;
  
class GFG
{
      
// This function returns
// count of number of pairs
// with sum equals to x.
static 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 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 Code
public static void main (String[] args) 
{
    int arr[] = {11, 15, 6, 7, 9, 10};
    int sum = 16;
    int n = arr.length;
  
    System.out.println(
            pairsInSortedRotated(arr, n, sum));
}
}
  
// This code is contributed by ajit

输出:

2

时间复杂度: O(n)
辅助空间: O(1)
Nikhil Jindal 提出了这种方法。

请参阅关于给定排序和旋转数组的完整文章,查找是否存在具有给定总和的对以获取更多详细信息!