📌  相关文章
📜  计算给定数组中的对(i,j),使得i <j和arr [i]> K * arr [j]

📅  最后修改于: 2021-05-17 22:58:10             🧑  作者: Mango

给定长度为N的数组arr []和整数K ,任务是计算对(i,j)的对数,以使i arr [i]> K * arr [j]

例子:

天真的方法:解决问题的最简单方法是遍历数组,对于每个索引,找到索引大于它的数字,这样当乘以K时,其中的元素小于当前索引的元素。

请按照以下步骤解决问题:

  1. 0初始化一个变量cnt ,以计算所需对的总数。
  2. 从左到右遍历数组。
  3. 对于每个可能的索引,例如i ,遍历索引i +1N – 1 ,如果发现任何元素(例如arr [j])使arr [j] * K小于arr ,则将cnt的值增加1 [i]
  4. 遍历数组后,将cnt打印为所需的对数。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to find the count required pairs
int getPairs(int arr[], int N, int K)
{
    // Stores count of pairs
    int count = 0;
  
    // Traverse the array
    for (int i = 0; i < N; i++) {
  
        for (int j = i + 1; j < N; j++) {
  
            // Check if the condition
            // is satisfied or not
            if (arr[i] > K * arr[i + 1])
                count++;
        }
    }
    cout << count;
}
  
// Driver Code
int main()
{
    int arr[] = { 5, 6, 2, 1 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 2;
  
    // Function Call
    getPairs(arr, N, K);
  
    return 0;
}


Java
// Java program for the above approach
class GFG
{
  
// Function to find the count required pairs
static void getPairs(int arr[], int N, int K)
{
    // Stores count of pairs
    int count = 0;
  
    // Traverse the array
    for (int i = 0; i < N; i++) 
    {
        for (int j = i + 1; j < N; j++) 
        {
  
            // Check if the condition
            // is satisfied or not
            if (arr[i] > K * arr[i + 1])
                count++;
        }
    }
    System.out.print(count);
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 5, 6, 2, 1 };
    int N = arr.length;
    int K = 2;
  
    // Function Call
    getPairs(arr, N, K);
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
  
# Function to find the count required pairs
def getPairs(arr, N, K):
      
    # Stores count of pairs
    count = 0
  
    # Traverse the array
    for i in range(N):
        for j in range(i + 1, N):
              
            # Check if the condition
            # is satisfied or not
            if (arr[i] > K * arr[i + 1]):
                count += 1
                  
    print(count)
  
# Driver Code
if __name__ == '__main__':
      
    arr = [ 5, 6, 2, 1 ]
    N   = len(arr)
    K = 2 
  
    # Function Call
    getPairs(arr, N, K)
  
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
  
class GFG
{
  
// Function to find the count required pairs
static void getPairs(int []arr, int N, int K)
{
    // Stores count of pairs
    int count = 0;
  
    // Traverse the array
    for (int i = 0; i < N; i++) 
    {
        for (int j = i + 1; j < N; j++) 
        {
  
            // Check if the condition
            // is satisfied or not
            if (arr[i] > K * arr[i + 1])
                count++;
        }
    }
    Console.Write(count);
}
  
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 5, 6, 2, 1 };
    int N = arr.Length;
    int K = 2;
  
    // Function Call
    getPairs(arr, N, K);
}
}
  
// This code is contributed by shikhasingrajput


C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to merge two sorted arrays
int merge(int arr[], int temp[],
          int l, int m, int r, int K)
{
    // i: index to left subarray
    int i = l;
  
    // j: index to right subarray
    int j = m + 1;
  
    // Stores count of pairs that
    // satisfy the given condition
    int cnt = 0;
  
    for (int l = 0; i <= m; i++) {
        bool found = false;
  
        // Traverse to check for the
        // valid conditions
        while (j <= r) {
  
            // If condition satifies
            if (arr[i] >= K * arr[j]) {
                found = true;
            }
            else
                break;
            j++;
        }
  
        // While a[i] > K*a[j] satisfies
        // increase j
  
        // All elements in the right
        // side of the left subarray
        // also satisies
        if (found) {
            cnt += j - (m + 1);
            j--;
        }
    }
  
    // Sort the two given arrays and
    // store in the resultant array
    int k = l;
    i = l;
    j = m + 1;
  
    while (i <= m && j <= r) {
  
        if (arr[i] <= arr[j])
            temp[k++] = arr[i++];
        else
            temp[k++] = arr[j++];
    }
  
    // Elements which are left
    // in the left subarray
    while (i <= m)
        temp[k++] = arr[i++];
  
    // Elements which are left
    // in the right subarray
    while (j <= r)
        temp[k++] = arr[j++];
  
    for (int i = l; i <= r; i++)
        arr[i] = temp[i];
  
    // Return the count obtained
    return cnt;
}
  
// Function to partiton array into two halves
int mergeSortUtil(int arr[], int temp[],
                  int l, int r, int K)
{
    int cnt = 0;
    if (l < r) {
  
        // Same as (l + r) / 2, but avoids
        // overflow for large l and h
        int m = (l + r) / 2;
  
        // Sort first and second halves
        cnt += mergeSortUtil(arr, temp,
                             l, m, K);
        cnt += mergeSortUtil(arr, temp,
                             m + 1, r, K);
  
        // Call the merging function
        cnt += merge(arr, temp, l,
                     m, r, K);
    }
  
    return cnt;
}
  
// Function to print the count of
// required pairs using Merge Sort
int mergeSort(int arr[], int N, int K)
{
    int temp[N];
  
    cout << mergeSortUtil(arr, temp, 0,
                          N - 1, K);
}
  
// Driver code
int main()
{
    int arr[] = { 5, 6, 2, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 2;
  
    // Function Call
    mergeSort(arr, N, K);
  
    return 0;
}


Java
// Java program for the above approach
class GFG 
{
      
    // Function to merge two sorted arrays
    static int merge(int arr[], int temp[],
              int l, int m, int r, int K)
    {
        
        // i: index to left subarray
        int i = l;
      
        // j: index to right subarray
        int j = m + 1;
      
        // Stores count of pairs that
        // satisfy the given condition
        int cnt = 0;
      
        for (i = l; i <= m; i++) 
        {
            boolean found = false;
      
            // Traverse to check for the
            // valid conditions
            while (j <= r) 
            {
      
                // If condition satifies
                if (arr[i] >= K * arr[j]) 
                {
                    found = true;
                }
                else
                    break;
                j++;
            }
      
            // While a[i] > K*a[j] satisfies
            // increase j
      
            // All elements in the right
            // side of the left subarray
            // also satisies
            if (found == true) 
            {
                cnt += j - (m + 1);
                j--;
            }
        }
      
        // Sort the two given arrays and
        // store in the resultant array
        int k = l;
        i = l;
        j = m + 1;
      
        while (i <= m && j <= r) 
        {
      
            if (arr[i] <= arr[j])
                temp[k++] = arr[i++];
            else
                temp[k++] = arr[j++];
        }
      
        // Elements which are left
        // in the left subarray
        while (i <= m)
            temp[k++] = arr[i++];
      
        // Elements which are left
        // in the right subarray
        while (j <= r)
            temp[k++] = arr[j++];
      
        for (i = l; i <= r; i++)
            arr[i] = temp[i];
      
        // Return the count obtained
        return cnt;
    }
      
    // Function to partiton array into two halves
    static int mergeSortUtil(int arr[], int temp[],
                      int l, int r, int K)
    {
        int cnt = 0;
        if (l < r)
        {
      
            // Same as (l + r) / 2, but avoids
            // overflow for large l and h
            int m = (l + r) / 2;
      
            // Sort first and second halves
            cnt += mergeSortUtil(arr, temp,
                                 l, m, K);
            cnt += mergeSortUtil(arr, temp,
                                 m + 1, r, K);
      
            // Call the merging function
            cnt += merge(arr, temp, l,
                         m, r, K);
        }    
        return cnt;
    }
      
    // Function to print the count of
    // required pairs using Merge Sort
    static void mergeSort(int arr[], int N, int K)
    {
        int temp[] = new int[N];
        System.out.print(mergeSortUtil(arr, temp, 0, N - 1, K));
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int arr[] = { 5, 6, 2, 5 };
        int N = arr.length;
        int K = 2;
      
        // Function Call
        mergeSort(arr, N, K);    
    }
}
  
// This code is contributed by AnkThon


Python3
# Python3 program for the above approach
  
# Function to merge two sorted arrays
def merge(arr, temp, l, m, r, K) :
  
    # i: index to left subarray
    i = l
   
    # j: index to right subarray
    j = m + 1
   
    # Stores count of pairs that
    # satisfy the given condition
    cnt = 0 
    for l in range(m + 1) :
        found = False
   
        # Traverse to check for the
        # valid conditions
        while (j <= r) :
   
            # If condition satifies
            if (arr[i] >= K * arr[j]) :
                found = True         
            else :
                break
            j += 1
   
        # While a[i] > K*a[j] satisfies
        # increase j
   
        # All elements in the right
        # side of the left subarray
        # also satisies
        if (found) :
            cnt += j - (m + 1)
            j -= 1
   
    # Sort the two given arrays and
    # store in the resultant array
    k = l
    i = l
    j = m + 1
   
    while (i <= m and j <= r) :
        if (arr[i] <= arr[j]) :
            temp[k] = arr[i]
            k += 1
            i += 1
        else :
            temp[k] = arr[j]
            k += 1
            j += 1
   
    # Elements which are left
    # in the left subarray
    while (i <= m) :
        temp[k] = arr[i]
        k += 1
        i += 1
   
    # Elements which are left
    # in the right subarray
    while (j <= r) :
        temp[k] = arr[j]
        k += 1
        j += 1 
    for i in range(l, r + 1) :
        arr[i] = temp[i]
   
    # Return the count obtained
    return cnt
   
# Function to partiton array into two halves
def mergeSortUtil(arr, temp, l, r, K) :
    cnt = 0
    if (l < r) :
   
        # Same as (l + r) / 2, but avoids
        # overflow for large l and h
        m = (l + r) // 2
   
        # Sort first and second halves
        cnt += mergeSortUtil(arr, temp, l, m, K)
        cnt += mergeSortUtil(arr, temp, m + 1, r, K)
   
        # Call the merging function
        cnt += merge(arr, temp, l, m, r, K) 
    return cnt
   
# Function to print the count of
# required pairs using Merge Sort
def mergeSort(arr, N, K) :
    temp = [0]*N
    print(mergeSortUtil(arr, temp, 0, N - 1, K))
  
  # Driver code
arr = [ 5, 6, 2, 5 ]
N = len(arr)
K = 2
  
# Function Call
mergeSort(arr, N, K)
  
# This code is contributed by divyeshrabadiya07.


C#
// C# program for the above approach
using System;
  
class GFG {
  
  // Function to merge two sorted arrays
  static int merge(int[] arr, int[] temp, int l, int m,
                   int r, int K)
  {
  
    // i: index to left subarray
    int i = l;
  
    // j: index to right subarray
    int j = m + 1;
  
    // Stores count of pairs that
    // satisfy the given condition
    int cnt = 0;
  
    for (i = l; i <= m; i++) {
      bool found = false;
  
      // Traverse to check for the
      // valid conditions
      while (j <= r) {
  
        // If condition satifies
        if (arr[i] >= K * arr[j]) {
          found = true;
        }
        else
          break;
        j++;
      }
  
      // While a[i] > K*a[j] satisfies
      // increase j
  
      // All elements in the right
      // side of the left subarray
      // also satisies
      if (found == true) {
        cnt += j - (m + 1);
        j--;
      }
    }
  
    // Sort the two given arrays and
    // store in the resultant array
    int k = l;
    i = l;
    j = m + 1;
  
    while (i <= m && j <= r)
    {
      if (arr[i] <= arr[j])
        temp[k++] = arr[i++];
      else
        temp[k++] = arr[j++];
    }
  
    // Elements which are left
    // in the left subarray
    while (i <= m)
      temp[k++] = arr[i++];
  
    // Elements which are left
    // in the right subarray
    while (j <= r)
      temp[k++] = arr[j++];
  
    for (i = l; i <= r; i++)
      arr[i] = temp[i];
  
    // Return the count obtained
    return cnt;
  }
  
  // Function to partiton array into two halves
  static int mergeSortUtil(int[] arr, int[] temp, int l,
                           int r, int K)
  {
    int cnt = 0;
    if (l < r) {
  
      // Same as (l + r) / 2, but avoids
      // overflow for large l and h
      int m = (l + r) / 2;
  
      // Sort first and second halves
      cnt += mergeSortUtil(arr, temp, l, m, K);
      cnt += mergeSortUtil(arr, temp, m + 1, r, K);
  
      // Call the merging function
      cnt += merge(arr, temp, l, m, r, K);
    }
    return cnt;
  }
  
  // Function to print the count of
  // required pairs using Merge Sort
  static void mergeSort(int[] arr, int N, int K)
  {
    int[] temp = new int[N];
    Console.WriteLine(
      mergeSortUtil(arr, temp, 0, N - 1, K));
  }
  
  // Driver code
  static public void Main()
  {
  
    int[] arr = new int[] { 5, 6, 2, 5 };
    int N = arr.Length;
    int K = 2;
  
    // Function Call
    mergeSort(arr, N, K);  
  }
}
  
// This code is contributed by Dharanendra L V


输出:
2

时间复杂度: O(N 2 )
辅助空间: O(N)

高效方法:想法是使用合并排序的概念,然后根据给定条件对数进行计数。请按照以下步骤解决问题:

  • 初始化一个变量,例如answer ,以计算满足给定条件的对的数量。
  • 重复将数组分为两个相等的部分或几乎相等的两个部分,直到每个分区中剩下一个元素为止。
  • 调用一个递归函数,该函数计算合并两个分区后满足条件arr [i]> K * arr [j]i
  • 通过初始化两个变量(分别为上半部分和下半部分的索引) ij来执行此操作。
  • 递增j直到arr [i]> K * arr [j]j <下半部分的大小。将(j –(mid + 1))添加答案中,并增加i
  • 完成上述步骤后,将答案的值打印为所需的对数。

下面是上述方法的实现:

C++

// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to merge two sorted arrays
int merge(int arr[], int temp[],
          int l, int m, int r, int K)
{
    // i: index to left subarray
    int i = l;
  
    // j: index to right subarray
    int j = m + 1;
  
    // Stores count of pairs that
    // satisfy the given condition
    int cnt = 0;
  
    for (int l = 0; i <= m; i++) {
        bool found = false;
  
        // Traverse to check for the
        // valid conditions
        while (j <= r) {
  
            // If condition satifies
            if (arr[i] >= K * arr[j]) {
                found = true;
            }
            else
                break;
            j++;
        }
  
        // While a[i] > K*a[j] satisfies
        // increase j
  
        // All elements in the right
        // side of the left subarray
        // also satisies
        if (found) {
            cnt += j - (m + 1);
            j--;
        }
    }
  
    // Sort the two given arrays and
    // store in the resultant array
    int k = l;
    i = l;
    j = m + 1;
  
    while (i <= m && j <= r) {
  
        if (arr[i] <= arr[j])
            temp[k++] = arr[i++];
        else
            temp[k++] = arr[j++];
    }
  
    // Elements which are left
    // in the left subarray
    while (i <= m)
        temp[k++] = arr[i++];
  
    // Elements which are left
    // in the right subarray
    while (j <= r)
        temp[k++] = arr[j++];
  
    for (int i = l; i <= r; i++)
        arr[i] = temp[i];
  
    // Return the count obtained
    return cnt;
}
  
// Function to partiton array into two halves
int mergeSortUtil(int arr[], int temp[],
                  int l, int r, int K)
{
    int cnt = 0;
    if (l < r) {
  
        // Same as (l + r) / 2, but avoids
        // overflow for large l and h
        int m = (l + r) / 2;
  
        // Sort first and second halves
        cnt += mergeSortUtil(arr, temp,
                             l, m, K);
        cnt += mergeSortUtil(arr, temp,
                             m + 1, r, K);
  
        // Call the merging function
        cnt += merge(arr, temp, l,
                     m, r, K);
    }
  
    return cnt;
}
  
// Function to print the count of
// required pairs using Merge Sort
int mergeSort(int arr[], int N, int K)
{
    int temp[N];
  
    cout << mergeSortUtil(arr, temp, 0,
                          N - 1, K);
}
  
// Driver code
int main()
{
    int arr[] = { 5, 6, 2, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 2;
  
    // Function Call
    mergeSort(arr, N, K);
  
    return 0;
}

Java

// Java program for the above approach
class GFG 
{
      
    // Function to merge two sorted arrays
    static int merge(int arr[], int temp[],
              int l, int m, int r, int K)
    {
        
        // i: index to left subarray
        int i = l;
      
        // j: index to right subarray
        int j = m + 1;
      
        // Stores count of pairs that
        // satisfy the given condition
        int cnt = 0;
      
        for (i = l; i <= m; i++) 
        {
            boolean found = false;
      
            // Traverse to check for the
            // valid conditions
            while (j <= r) 
            {
      
                // If condition satifies
                if (arr[i] >= K * arr[j]) 
                {
                    found = true;
                }
                else
                    break;
                j++;
            }
      
            // While a[i] > K*a[j] satisfies
            // increase j
      
            // All elements in the right
            // side of the left subarray
            // also satisies
            if (found == true) 
            {
                cnt += j - (m + 1);
                j--;
            }
        }
      
        // Sort the two given arrays and
        // store in the resultant array
        int k = l;
        i = l;
        j = m + 1;
      
        while (i <= m && j <= r) 
        {
      
            if (arr[i] <= arr[j])
                temp[k++] = arr[i++];
            else
                temp[k++] = arr[j++];
        }
      
        // Elements which are left
        // in the left subarray
        while (i <= m)
            temp[k++] = arr[i++];
      
        // Elements which are left
        // in the right subarray
        while (j <= r)
            temp[k++] = arr[j++];
      
        for (i = l; i <= r; i++)
            arr[i] = temp[i];
      
        // Return the count obtained
        return cnt;
    }
      
    // Function to partiton array into two halves
    static int mergeSortUtil(int arr[], int temp[],
                      int l, int r, int K)
    {
        int cnt = 0;
        if (l < r)
        {
      
            // Same as (l + r) / 2, but avoids
            // overflow for large l and h
            int m = (l + r) / 2;
      
            // Sort first and second halves
            cnt += mergeSortUtil(arr, temp,
                                 l, m, K);
            cnt += mergeSortUtil(arr, temp,
                                 m + 1, r, K);
      
            // Call the merging function
            cnt += merge(arr, temp, l,
                         m, r, K);
        }    
        return cnt;
    }
      
    // Function to print the count of
    // required pairs using Merge Sort
    static void mergeSort(int arr[], int N, int K)
    {
        int temp[] = new int[N];
        System.out.print(mergeSortUtil(arr, temp, 0, N - 1, K));
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int arr[] = { 5, 6, 2, 5 };
        int N = arr.length;
        int K = 2;
      
        // Function Call
        mergeSort(arr, N, K);    
    }
}
  
// This code is contributed by AnkThon

Python3

# Python3 program for the above approach
  
# Function to merge two sorted arrays
def merge(arr, temp, l, m, r, K) :
  
    # i: index to left subarray
    i = l
   
    # j: index to right subarray
    j = m + 1
   
    # Stores count of pairs that
    # satisfy the given condition
    cnt = 0 
    for l in range(m + 1) :
        found = False
   
        # Traverse to check for the
        # valid conditions
        while (j <= r) :
   
            # If condition satifies
            if (arr[i] >= K * arr[j]) :
                found = True         
            else :
                break
            j += 1
   
        # While a[i] > K*a[j] satisfies
        # increase j
   
        # All elements in the right
        # side of the left subarray
        # also satisies
        if (found) :
            cnt += j - (m + 1)
            j -= 1
   
    # Sort the two given arrays and
    # store in the resultant array
    k = l
    i = l
    j = m + 1
   
    while (i <= m and j <= r) :
        if (arr[i] <= arr[j]) :
            temp[k] = arr[i]
            k += 1
            i += 1
        else :
            temp[k] = arr[j]
            k += 1
            j += 1
   
    # Elements which are left
    # in the left subarray
    while (i <= m) :
        temp[k] = arr[i]
        k += 1
        i += 1
   
    # Elements which are left
    # in the right subarray
    while (j <= r) :
        temp[k] = arr[j]
        k += 1
        j += 1 
    for i in range(l, r + 1) :
        arr[i] = temp[i]
   
    # Return the count obtained
    return cnt
   
# Function to partiton array into two halves
def mergeSortUtil(arr, temp, l, r, K) :
    cnt = 0
    if (l < r) :
   
        # Same as (l + r) / 2, but avoids
        # overflow for large l and h
        m = (l + r) // 2
   
        # Sort first and second halves
        cnt += mergeSortUtil(arr, temp, l, m, K)
        cnt += mergeSortUtil(arr, temp, m + 1, r, K)
   
        # Call the merging function
        cnt += merge(arr, temp, l, m, r, K) 
    return cnt
   
# Function to print the count of
# required pairs using Merge Sort
def mergeSort(arr, N, K) :
    temp = [0]*N
    print(mergeSortUtil(arr, temp, 0, N - 1, K))
  
  # Driver code
arr = [ 5, 6, 2, 5 ]
N = len(arr)
K = 2
  
# Function Call
mergeSort(arr, N, K)
  
# This code is contributed by divyeshrabadiya07.

C#

// C# program for the above approach
using System;
  
class GFG {
  
  // Function to merge two sorted arrays
  static int merge(int[] arr, int[] temp, int l, int m,
                   int r, int K)
  {
  
    // i: index to left subarray
    int i = l;
  
    // j: index to right subarray
    int j = m + 1;
  
    // Stores count of pairs that
    // satisfy the given condition
    int cnt = 0;
  
    for (i = l; i <= m; i++) {
      bool found = false;
  
      // Traverse to check for the
      // valid conditions
      while (j <= r) {
  
        // If condition satifies
        if (arr[i] >= K * arr[j]) {
          found = true;
        }
        else
          break;
        j++;
      }
  
      // While a[i] > K*a[j] satisfies
      // increase j
  
      // All elements in the right
      // side of the left subarray
      // also satisies
      if (found == true) {
        cnt += j - (m + 1);
        j--;
      }
    }
  
    // Sort the two given arrays and
    // store in the resultant array
    int k = l;
    i = l;
    j = m + 1;
  
    while (i <= m && j <= r)
    {
      if (arr[i] <= arr[j])
        temp[k++] = arr[i++];
      else
        temp[k++] = arr[j++];
    }
  
    // Elements which are left
    // in the left subarray
    while (i <= m)
      temp[k++] = arr[i++];
  
    // Elements which are left
    // in the right subarray
    while (j <= r)
      temp[k++] = arr[j++];
  
    for (i = l; i <= r; i++)
      arr[i] = temp[i];
  
    // Return the count obtained
    return cnt;
  }
  
  // Function to partiton array into two halves
  static int mergeSortUtil(int[] arr, int[] temp, int l,
                           int r, int K)
  {
    int cnt = 0;
    if (l < r) {
  
      // Same as (l + r) / 2, but avoids
      // overflow for large l and h
      int m = (l + r) / 2;
  
      // Sort first and second halves
      cnt += mergeSortUtil(arr, temp, l, m, K);
      cnt += mergeSortUtil(arr, temp, m + 1, r, K);
  
      // Call the merging function
      cnt += merge(arr, temp, l, m, r, K);
    }
    return cnt;
  }
  
  // Function to print the count of
  // required pairs using Merge Sort
  static void mergeSort(int[] arr, int N, int K)
  {
    int[] temp = new int[N];
    Console.WriteLine(
      mergeSortUtil(arr, temp, 0, N - 1, K));
  }
  
  // Driver code
  static public void Main()
  {
  
    int[] arr = new int[] { 5, 6, 2, 5 };
    int N = arr.Length;
    int K = 2;
  
    // Function Call
    mergeSort(arr, N, K);  
  }
}
  
// This code is contributed by Dharanendra L V
输出:
2

时间复杂度: O(N * log N)
辅助空间: O(N)