📌  相关文章
📜  最长子数组,其第一个元素大于或等于最后一个元素

📅  最后修改于: 2021-04-29 12:04:48             🧑  作者: Mango

给定n个整数的数组arr [0..n-1],请找到最大长度的子数组,使其第一个元素大于或等于子数组的最后一个元素。

例子:

Input : arr[] = {-5, -1, 7, 5, 1, -2}
Output : 5
Explanation : Subarray {-1, 7, 5, 1, -2} forms maximum 
length subarray with its first element greater than last.

Input : arr[] = {1, 5, 7}
Output : 1

天真的方法对子数组的每个可能的开始和结束元素使用两个嵌套循环,如果满足条件,则相应地更新答案。
时间复杂度– O(n ^ 2)

更好的方法是使用二进制搜索。在这种方法中,对于数组中的每个元素,我们将以该元素结尾的子数组的长度最大化。然后我们取所有长度中的最大值。

我们将使用另一个数组作为搜索空间,以选择其中的起始元素。如果该元素大于搜索空间中存在的所有先前元素,则在遍历数组时将继续在其中添加元素。
此处的主要观察结果是,仅当元素大于搜索空间的所有元素时,我们才将其添加到搜索空间中,因为如果该元素比其他任何元素都低,那么它将永远不会被选择为最大元素的第一个元素长度子数组,因为我们会有更好的选择。
由于搜索空间总是按升序排序,因此我们只需要将数组的当前元素与搜索空间的最后一个元素进行比较,并且当且仅当其大于最后一个元素时,才将其添加到搜索空间中。

下面是上述方法的实现

C++
// CPP program to find length of the longest
// array with first element smaller than or
// equal to last element.
#include 
#include 
using namespace std;
  
// Search function for searching the first element of the
// subarray which is greater or equal to the last element(num)
int binarySearch(int* searchSpace, int s, int e, int num)
{
    int ans;
  
    while (s <= e) {
        int mid = (s + e) / 2;
  
        if (searchSpace[mid] >= num) {
            ans = mid;
            e = mid - 1;
        }
        else
            s = mid + 1;
    }
  
    return ans;
}
  
// Returns length of the longest array with first
// element smaller than the last element.
int longestSubArr(int* arr, int n)
{
    // Search space for the potential first elements.
    int searchSpace[n];
  
    // It will store the Indexes of the elements
    // of search space in the original array.
    int index[n];
  
    // Initially the search space is empty.
    int j = 0;
    int ans = 0;
  
    for (int i = 0; i < n; ++i) {
  
        // We will add an ith element in the search 
        // space if the search space is empty or if 
        // the ith element is greater than the last
        // element of the search space.
        if (j == 0 or searchSpace[j - 1] < arr[i]) {
            searchSpace[j] = arr[i];
            index[j] = i;
            j++;
        }
  
        // we will search for the index first element in the
        // search space and we will use it find the
        // index of it in the original array.
        int idx = binarySearch(searchSpace, 0, j - 1, arr[i]);
  
        // Update the answer if the length of the subarray is
        // greater than the previously calculated lengths.
        ans = max(ans, i - index[idx] + 1);
    }
    return ans;
}
  
int main(int argc, char const* argv[])
{
    int arr[] = { -5, -1, 7, 5, 1, -2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << longestSubArr(arr, n) << endl;
    return 0;
}


Java
// Java program to find length 
// of the longest array with 
// first element smaller than 
// or equal to last element.
class GFG 
{
  
// Search function for searching 
// the first element of the
// subarray which is greater or 
// equal to the last element(num)
static int binarySearch(int []searchSpace, int s,
                        int e, int num)
{
int ans = 0;
  
while (s <= e) 
{
    int mid = (s + e) / 2;
  
    if (searchSpace[mid] >= num) 
    {
        ans = mid;
        e = mid - 1;
    }
    else
        s = mid + 1;
}
  
return ans;
}
  
// Returns length of the longest 
// array with first element smaller
// than the last element.
static int longestSubArr(int []arr, int n)
{
// Search space for the 
// potential first elements.
int []searchSpace = new int[n];
  
// It will store the Indexes 
// of the elements of search
// space in the original array.
int []index = new int[n];
  
// Initially the search
// space is empty.
int j = 0;
int ans = 0;
  
for (int i = 0; i < n; ++i)
{
  
    // We will add an ith element 
    // in the search space if the 
    // search space is empty or if 
    // the ith element is greater 
    // than the last element of 
    // the search space.
    if (j == 0 || searchSpace[j - 1] < arr[i]) 
    {
        searchSpace[j] = arr[i];
        index[j] = i;
        j++;
    }
  
    // we will search for the index 
    // first element in the search 
    // space and we will use it find
    // the index of it in the original array.
    int idx = binarySearch(searchSpace, 0,
                           j - 1, arr[i]);
  
    // Update the answer if the 
    // length of the subarray is
    // greater than the previously 
    // calculated lengths.
    ans = Math.max(ans, i - index[idx] + 1);
}
return ans;
}
  
// Driver Code
public static void main(String[] args) 
{
    int arr[] = { -5, -1, 7, 5, 1, -2 };
    int n = arr.length;
    System.out.println(longestSubArr(arr, n));
}
}
  
// This code is contributed
// by ChitraNayal


Python 3
# Python 3 program to find 
# length of the longest array 
# with first element smaller 
# than or equal to last element.
  
# Search function for searching
# the first element of the
# subarray which is greater or
# equal to the last element(num)
def binarySearch(searchSpace, s, e, num):
  
    while (s <= e):
        mid = (s + e) // 2
  
        if searchSpace[mid] >= num :
            ans = mid
            e = mid - 1
          
        else:
            s = mid + 1
  
    return ans
  
# Returns length of the longest 
# array with first element
# smaller than the last element.
def longestSubArr(arr, n):
  
    # Search space for the 
    # potential first elements.
    searchSpace = [None] * n
  
    # It will store the Indexes
    # of the elements of search 
    # space in the original array.
    index = [None] * n
  
    # Initially the search 
    # space is empty.
    j = 0
    ans = 0
  
    for i in range(n): 
  
        # We will add an ith element 
        # in the search space if the
        # search space is empty or if 
        # the ith element is greater 
        # than the last element of 
        # the search space.
        if (j == 0 or searchSpace[j - 1] < arr[i]) :
            searchSpace[j] = arr[i]
            index[j] = i
            j += 1
  
        # we will search for the index 
        # first element in the search
        # space and we will use it 
        # find the index of it in the 
        # original array.
        idx = binarySearch(searchSpace, 0, 
                           j - 1, arr[i])
  
        # Update the answer if the length 
        # of the subarray is greater than 
        # the previously calculated lengths.
        ans = max(ans, i - index[idx] + 1)
      
    return ans
  
if __name__ == "__main__":
    arr = [ -5, -1, 7, 5, 1, -2 ]
    n = len(arr)
    print(longestSubArr(arr, n))
  
# This code is contributed
# by ChitraNayal


C#
// C# program to find length 
// of the longest array with
// first element smaller than 
// or equal to last element.
using System;
  
class GFG 
{
  
// Search function for searching 
// the first element of the
// subarray which is greater or 
// equal to the last element(num)
static int binarySearch(int[] searchSpace, 
                        int s, int e, int num)
{
int ans = 0;
  
while (s <= e) 
{
    int mid = (s + e) / 2;
  
    if (searchSpace[mid] >= num) 
    {
        ans = mid;
        e = mid - 1;
    }
    else
        s = mid + 1;
}
  
return ans;
}
  
// Returns length of the longest 
// array with first element smaller 
// than the last element.
static int longestSubArr(int[] arr, int n)
{
      
// Search space for the
// potential first elements.
int[] searchSpace = new int[n];
  
// It will store the Indexes 
// of the elements of search
// space in the original array.
int[] index = new int[n];
  
// Initially the search 
// space is empty.
int j = 0;
int ans = 0;
  
for (int i = 0; i < n; ++i) 
{
  
    // We will add an ith element 
    // in the search space if the 
    // search space is empty or if 
    // the ith element is greater 
    // than the last element of 
    // the search space.
    if (j == 0 || searchSpace[j - 1] < arr[i]) 
    {
        searchSpace[j] = arr[i];
        index[j] = i;
        j++;
    }
  
    // we will search for the index 
    // first element in the search 
    // space and we will use it find the
    // index of it in the original array.
    int idx = binarySearch(searchSpace, 0,
                           j - 1, arr[i]);
  
    // Update the answer if the
    // length of the subarray is
    // greater than the previously
    // calculated lengths.
    ans = Math.Max(ans, i - index[idx] + 1);
}
return ans;
}
  
// Driver code
public static void Main() 
{
    int[] arr = { -5, -1, 7, 5, 1, -2 };
    int n = arr.Length;
    Console.Write(longestSubArr(arr, n));
}
}
  
// This code is contributed
// by ChitraNayal


PHP
= $num) 
        {
            $ans = $mid;
            $e = $mid - 1;
        }
        else
        {
            $s = $mid + 1;
        }
    }
  
    return $ans;
}
  
// Returns length of the longest 
// array with first element smaller
// than the last element.
function longestSubArr(&$arr, $n)
{
    // Search space for the
    // potential first elements.
  
    // It will store the Indexes 
    // of the elements of search 
    // space in the original array.
      
    // Initially the search
    // space is empty.
    $j = 0;
    $ans = 0;
    for ($i = 0; $i < $n; ++$i) 
    {
  
        // We will add an ith element 
        // in the search space if the 
        // search space is empty or if 
        // the ith element is greater 
        // than the last element of the
        // search space.
        if ($j == 0 or 
            $searchSpace[$j - 1] < $arr[$i]) 
        {
            $searchSpace[$j] = $arr[$i];
            $index[$j] = $i;
            $j++;
        }
      
  
        // we will search for the index 
        // first element in the search 
        // space and we will use it find 
        // the index of it in the original
        // array.
        $idx = binarySearch($searchSpace, 0, 
                            $j - 1, $arr[$i]);
  
        // Update the answer if the length 
        // of the subarray is greater than 
        // the previously calculated lengths.
        $ans = max($ans, $i - $index[$idx] + 1);
    }
    return $ans;
}
  
// Driver code
$arr = array(-5, -1, 7, 5, 1, -2);
$n = sizeof($arr);
echo (longestSubArr($arr, $n)) ; 
  
// This code is contributed
// by Shivi_Aggarwal
?>


输出

5

时间复杂度–(N * log N)
二进制搜索函数需要登录N次,它将被调用N次。