📜  在线性时间内找到大小为 3 的排序子序列

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

在线性时间内找到大小为 3 的排序子序列

给定一个包含 n 个整数的数组,在 0(n) 时间内找到满足 a[i] < a[j] < a[k] 和 i < j < k 的 3 个元素。如果有多个这样的三元组,则打印其中任何一个。

例子:

Input: arr[] = {12, 11, 10, 5, 6, 2, 30}
Output: 5, 6, 30
Explanation: As 5 < 6 < 30, and they 
appear in the same sequence in the array 

Input: arr[] = {1, 2, 3, 4}
Output: 1, 2, 3 OR 1, 2, 4 OR 2, 3, 4
Explanation: As the array is sorted, for every i, j, k,
where i < j < k, arr[i] < arr[j] < arr[k] 

Input: arr[] = {4, 3, 2, 1}
Output: No such triplet exists.

方法一:

提示:使用辅助空间。
解决方案:所以,主要动机是在数组的左侧找到一个比自己小的元素,在数组的右侧找到一个比自己大的元素,如果有这样的元素,那么存在一个满足条件的三元组。

方法:这可以通过非常简单的方式解决。要在数组的左侧找到一个元素小于自身的元素,请检查该元素是否是最小元素,同时从起始索引(0)遍历数组,并检查是否有更大的元素比它自己在数组的右侧检查该元素是否是最大的元素,同时从数组的末尾遍历,即 (n-1)。如果该元素不是从 0 到该索引的最小元素,则它的左侧有一个小于自身的元素,类似地,如果该元素不是从该索引到最后一个索引的最大元素,则存在一个更大的元素在它的右侧。

算法

  1. 创建一个较小的辅助数组[0..n-1]。 small[i] 存储小于 arr[i] 且位于左侧的数字的索引。如果没有这样的元素,则数组包含 -1。
  2. 创建另一个更大的辅助数组[0..n-1]。 Greater[i] 存储大于 arr[i] 且位于 arr[i] 右侧的数字的索引。如果没有这样的元素,则数组包含 -1。
  3. 最后遍历smaller[]和greater[],找到smaller[i]和greater[i]都不等于-1的索引[i]。
C++
// C++ program to find a sorted
// sub-sequence of size 3
#include 
using namespace std;
  
// A function to fund a sorted
// sub-sequence of size 3
void find3Numbers(int arr[], int n)
{
    // Index of maximum element
    // from right side
    int max = n - 1;
  
    // Index of minimum element
    // from left side
    int min = 0;
    int i;
  
    // Create an array that will store
    // index of a smaller element on left side.
    // If there is no smaller element on left
    // side, then smaller[i] will be -1.
    int* smaller = new int[n];
  
    // first entry will always be -1
    smaller[0] = -1;
    for (i = 1; i < n; i++) {
        if (arr[i] <= arr[min]) {
            min = i;
            smaller[i] = -1;
        }
        else
            smaller[i] = min;
    }
  
    // Create another array that will
    // store index of a greater element
    // on right side. If there is no greater
    // element on right side, then
    // greater[i] will be -1.
    int* greater = new int[n];
  
    // last entry will always be -1
    greater[n - 1] = -1;
    for (i = n - 2; i >= 0; i--) {
        if (arr[i] >= arr[max]) {
            max = i;
            greater[i] = -1;
        }
        else
            greater[i] = max;
    }
  
    // Now find a number which has both
    // a greater number on right side and
    // smaller number on left side
    for (i = 0; i < n; i++) {
        if (smaller[i] != -1 && greater[i] != -1) {
            cout << arr[smaller[i]]
                 << " " << arr[i] << " "
                 << arr[greater[i]];
            return;
        }
    }
  
    // If we reach number, then there are
    // no such 3 numbers
    cout << "No such triplet found";
  
    // Free the dynamically allocated memory
    // to avoid memory leak
    delete[] smaller;
    delete[] greater;
  
    return;
}
  
// Driver code
int main()
{
    int arr[] = { 12, 11, 10, 5, 6, 2, 30 };
    int n = sizeof(arr) / sizeof(arr[0]);
    find3Numbers(arr, n);
    return 0;
    a greater number on
}
  
// This is code is contributed by rathbhupendra


C
// C program to find a sorted
// sub-sequence of size 3
#include 
  
// A function to fund a sorted
// sub-sequence of size 3
void find3Numbers(int arr[], int n)
{
    // Index of maximum element
    // from right side
    int max = n - 1;
  
    // Index of minimum element
    // from left side
    int min = 0;
    int i;
  
    // Create an array that will store
    // index of a smaller element on left side.
    // If there is no smaller element on left side,
    // then smaller[i] will be -1.
    int* smaller = new int[n];
  
    // first entry will always be -1
    smaller[0] = -1;
    for (i = 1; i < n; i++) {
        if (arr[i] <= arr[min]) {
            min = i;
            smaller[i] = -1;
        }
        else
            smaller[i] = min;
    }
  
    // Create another array that will
    // store index of a greater element
    // on right side. If there is no greater
    // element on right side, then
    // greater[i] will be -1.
    int* greater = new int[n];
  
    // last entry will always be -1
    greater[n - 1] = -1;
    for (i = n - 2; i >= 0; i--) {
        if (arr[i] >= arr[max]) {
            max = i;
            greater[i] = -1;
        }
        else
            greater[i] = max;
    }
  
    // Now find a number which has
    // both a greater number on right
    // side and smaller number on left side
    for (i = 0; i < n; i++) {
        if (smaller[i] != -1 && greater[i] != -1) {
            printf("%d %d %d", arr[smaller[i]],
                   arr[i], arr[greater[i]]);
            return;
        }
    }
  
    // If we reach number, then
    // there are no such 3 numbers
    printf("No such triplet found");
  
    // Free the dynamically allocated memory
    // to avoid memory leak
    delete[] smaller;
    delete[] greater;
  
    return;
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 12, 11, 10, 5, 6, 2, 30 };
    int n = sizeof(arr) / sizeof(arr[0]);
    find3Numbers(arr, n);
    return 0;
}


Java
// Java program to find a sorted
// sub-sequence of size 3
import java.io.*;
  
class SortedSubsequence {
    // A function to find a sorted
    // sub-sequence of size 3
    static void find3Numbers(int arr[])
    {
        int n = arr.length;
  
        // Index of maximum element
        // from right side
        int max = n - 1;
  
        // Index of minimum element
        // from left side
        int min = 0;
        int i;
  
        // Create an array that will store
        // index of a smaller element on left side.
        // If there is no smaller element on left
        // side, then smaller[i] will be -1.
        int[] smaller = new int[n];
  
        // first entry will always be -1
        smaller[0] = -1;
        for (i = 1; i < n; i++) {
            if (arr[i] <= arr[min]) {
                min = i;
                smaller[i] = -1;
            }
            else
                smaller[i] = min;
        }
  
        // Create another array that will
        // store index of a greater element
        // on right side. If there is no greater
        // element on right side, then greater[i]
        // will be -1.
        int[] greater = new int[n];
  
        // last entry will always be -1
        greater[n - 1] = -1;
        for (i = n - 2; i >= 0; i--) {
            if (arr[i] >= arr[max]) {
                max = i;
                greater[i] = -1;
            }
            else
                greater[i] = max;
        }
  
        // Now find a number which has
        // both greater number on right
        // side and smaller number on left side
        for (i = 0; i < n; i++) {
            if (
                smaller[i] != -1 && greater[i] != -1) {
                System.out.print(
                    arr[smaller[i]] + " " + arr[i]
                    + " " + arr[greater[i]]);
                return;
            }
        }
  
        // If we reach number, then there
        // are no such 3 numbers
        System.out.println("No such triplet found");
        return;
    }
  
    public static void main(String[] args)
    {
        int arr[] = { 12, 11, 10, 5, 6, 2, 30 };
        find3Numbers(arr);
    }
}
/* This code is contributed by Devesh Agrawal*/


Python
# Python program to fund a sorted
# sub-sequence of size 3
  
def find3numbers(arr):
    n = len(arr)
  
# Index of maximum element from right side
    max = n-1
  
# Index of minimum element from left side 
    min = 0
  
    # Create an array that will store 
    # index of a smaller element on left side. 
    # If there is no smaller element on left side,
# then smaller[i] will be -1.
    smaller = [0]*10000
    smaller[0] = -1
    for i in range(1, n):
        if (arr[i] <= arr[min]):
            min = i
            smaller[i] = -1
        else:
            smaller[i] = min
  
    # Create another array that will 
    # store index of a greater element 
    # on right side. If there is no greater 
# element on right side, then greater[i] 
# will be -1.
    greater = [0]*10000
    greater[n-1] = -1
  
    for i in range(n-2, -1, -1):
        if (arr[i] >= arr[max]):
            max = i
            greater[i] = -1
  
        else:
            greater[i] = max
  
    # Now find a number which has 
    # both a greater number on right 
# side and smaller number on left side
    for i in range(0, n):
        if smaller[i] != -1 and greater[i] != -1:
            print arr[smaller[i]], arr[i], arr[greater[i]]
            return
  
    # If we reach here, then there are no such 3 numbers
    print "No triplet found"
    return
  
  
# Driver function to test above function
arr = [12, 11, 10, 5, 6, 2, 30]
find3numbers(arr)
  
# This code is contributed by Devesh Agrawal


C#
// C# program to find a sorted
// subsequence of size 3
using System;
  
class SortedSubsequence {
  
    // A function to find a sorted
    // subsequence of size 3
    static void find3Numbers(int[] arr)
    {
        int n = arr.Length;
  
        // Index of maximum element from right side
        int max = n - 1;
  
        // Index of minimum element from left side
        int min = 0;
        int i;
  
        // Create an array that will store index
        // of a smaller element on left side.
        // If there is no smaller element
        // on left side, then smaller[i] will be -1.
        int[] smaller = new int[n];
  
        // first entry will always be -1
        smaller[0] = -1;
        for (i = 1; i < n; i++) {
            if (arr[i] <= arr[min]) {
                min = i;
                smaller[i] = -1;
            }
            else
                smaller[i] = min;
        }
  
        // Create another array that will store
        // index of a greater element on right side.
        // If there is no greater element on
        // right side, then greater[i] will be -1.
        int[] greater = new int[n];
  
        // last entry will always be -1
        greater[n - 1] = -1;
        for (i = n - 2; i >= 0; i--) {
            if (arr[i] >= arr[max]) {
                max = i;
                greater[i] = -1;
            }
            else
                greater[i] = max;
        }
  
        // Now find a number which has
        // both a greater number on right side
        // and smaller number on left side
        for (i = 0; i < n; i++) {
            if (smaller[i] != -1 && greater[i] != -1) {
                Console.Write(
                    arr[smaller[i]] + " " + arr[i]
                    + " " + arr[greater[i]]);
                return;
            }
        }
  
        // If we reach number, then there
        // are no such 3 numbers
        Console.Write("No such triplet found");
        return;
    }
  
    // Driver code
    public static void Main()
    {
        int[] arr = { 12, 11, 10, 5, 6, 2, 30 };
        find3Numbers(arr);
    }
}
  
/* This code is contributed by vt_m*/


PHP
= 0; $i--)
    {
        if ($arr[$i] >= $arr[$max])
        {
            $max = $i;
            $greater[$i] = -1;
        }
        else
            $greater[$i] = $max;
    }
      
    // Now find a number which has both 
    // a greater number on right side 
    // and smaller number on left side
    for ($i = 0; $i < $n; $i++)
    {
        if ($smaller[$i] != -1 && 
            $greater[$i] != -1)
        {
            echo $arr[$smaller[$i]]." ".
                      $arr[$i] . " " . 
                      $arr[$greater[$i]];
            return;
        }
    }
      
    // If we reach number, then there
    // are no such 3 numbers
    printf("No such triplet found");
      
    return;
}
  
// Driver Code
$arr = array(12, 11, 10, 5, 6, 2, 30);
$n = sizeof($arr);
find3Numbers($arr, $n);
  
// This code is contributed 
// by ChitraNayal
?>


Javascript


C++
// C++ Program for above approach
#include 
using namespace std;
  
// Function to find the triplet
void find3Numbers(vector& nums) 
{
    
  // If number of elements < 3
  // then no triplets are possible
  if (nums.size() < 3){
    cout << "No such triplet found";
    return;
  }
    
  // track best sequence length 
  // (not current sequence length)
  int seq = 1;        
    
  // min number in array
  int min_num = nums[0];  
    
  // least max number in best sequence 
  // i.e. track arr[j] (e.g. in 
  // array {1, 5, 3} our best sequence 
  // would be {1, 3} with arr[j] = 3)
  int max_seq = INT_MAX;      
    
  // save arr[i]
  int store_min = min_num;   
    
  // Iterate from 1 to nums.size()
  for (int i = 1; i < nums.size(); i++) 
  {
    if (nums[i] == min_num)
      continue;
      
    else if (nums[i] < min_num) 
    {
      min_num = nums[i];
      continue;
    } 
      
    // this condition is only hit 
    // when current sequence size is 2
    else if (nums[i] < max_seq) {    
        
      // update best sequence max number 
      // to a smaller value 
      // (i.e. we've found a 
      // smaller value for arr[j])
      max_seq = nums[i];       
        
      // store best sequence start value 
      // i.e. arr[i]
      store_min = min_num;            
    } 
      
    // Increase best sequence length & 
    // save next number in our triplet
    else if (nums[i] > max_seq) 
    {
      // We've found our arr[k]!
      // Print the output        
        cout << "Triplet: " << store_min << 
                 ", " << max_seq << ", " << 
                           nums[i] << endl;
        return;
    }
  }
    
  // No triplet found
  cout << "No such triplet found";
}
  
// Driver Code
int main() {
  vector nums {1,2,-1,7,5};
    
  // Function Call
  find3Numbers(nums);
}


Java
// Java Program for above approach
class Main 
{ 
    // Function to find the triplet
    public static void find3Numbers(int[] nums) 
    {
         
      // If number of elements < 3
      // then no triplets are possible
      if (nums.length < 3){
        System.out.print("No such triplet found");
        return;
      }
         
      // track best sequence length 
      // (not current sequence length)
      int seq = 1;        
         
      // min number in array
      int min_num = nums[0];  
         
      // least max number in best sequence 
      // i.e. track arr[j] (e.g. in 
      // array {1, 5, 3} our best sequence 
      // would be {1, 3} with arr[j] = 3)
      int max_seq = Integer.MIN_VALUE;      
         
      // save arr[i]
      int store_min = min_num;   
         
      // Iterate from 1 to nums.size()
      for (int i = 1; i < nums.length; i++) 
      {
        if (nums[i] == min_num)
          continue;
           
        else if (nums[i] < min_num) 
        {
          min_num = nums[i];
          continue;
        } 
           
        // this condition is only hit 
        // when current sequence size is 2
        else if (nums[i] < max_seq) {    
             
          // update best sequence max number 
          // to a smaller value 
          // (i.e. we've found a 
          // smaller value for arr[j])
          max_seq = nums[i];       
             
          // store best sequence start value 
          // i.e. arr[i]
          store_min = min_num;            
        } 
           
        // Increase best sequence length & 
        // save next number in our triplet
        else if (nums[i] > max_seq) 
        {    
          seq++;
             
          // We've found our arr[k]!
          // Print the output
          if (seq == 3) 
          {            
            System.out.println("Triplet: " + store_min +
                               ", " + max_seq + ", " + nums[i]);
            return;
          }
          max_seq = nums[i];
        }
      }
         
      // No triplet found
      System.out.print("No such triplet found");
    }
      
    // Driver program 
    public static void main(String[] args) 
    { 
        int[] nums = {1,2,-1,7,5};
     
        // Function Call
        find3Numbers(nums); 
    } 
} 
  
// This code is contributed by divyesh072019


Python3
# Python3 Program for above approach
import sys
  
# Function to find the triplet
def find3Numbers(nums):
    
  # If number of elements < 3
  # then no triplets are possible
  if (len(nums) < 3):
    print("No such triplet found", end = '')
    return
    
  # Track best sequence length 
  # (not current sequence length)
  seq = 1    
    
  # min number in array
  min_num = nums[0]
    
  # Least max number in best sequence 
  # i.e. track arr[j] (e.g. in 
  # array {1, 5, 3} our best sequence 
  # would be {1, 3} with arr[j] = 3)
  max_seq = -sys.maxsize - 1   
    
  # Save arr[i]
  store_min = min_num   
    
  # Iterate from 1 to nums.size()
  for i in range(1, len(nums)):
    if (nums[i] == min_num):
      continue
    elif (nums[i] < min_num):
      min_num = nums[i]
      continue
        
    # This condition is only hit 
    # when current sequence size is 2
    elif (nums[i] < max_seq):
        
      # Update best sequence max number 
      # to a smaller value 
      # (i.e. we've found a 
      # smaller value for arr[j])
      max_seq = nums[i]    
        
      # Store best sequence start value 
      # i.e. arr[i]
      store_min = min_num           
        
    # Increase best sequence length & 
    # save next number in our triplet
    elif (nums[i] > max_seq):
      if seq == 1:
        store_min = min_num
      seq += 1
        
      # We've found our arr[k]!
      # Print the output
      if (seq == 3):
        print("Triplet: " + str(store_min) +
              ", " + str(max_seq) + ", " +
                     str(nums[i]))
          
        return
        
      max_seq = nums[i]
     
  # No triplet found
  print("No such triplet found", end = '')
    
# Driver Code
if __name__=='__main__':
    
  nums = [ 1, 2, -1, 7, 5 ]
    
  # Function Call
  find3Numbers(nums)
  
# This code is contributed by rutvik_56


C#
// C# Program for above approach
using System;
class GFG {
      
    // Function to find the triplet
    static void find3Numbers(int[] nums) 
    {
          
      // If number of elements < 3
      // then no triplets are possible
      if (nums.Length < 3){
        Console.Write("No such triplet found");
        return;
      }
          
      // track best sequence length 
      // (not current sequence length)
      int seq = 1;        
          
      // min number in array
      int min_num = nums[0];  
          
      // least max number in best sequence 
      // i.e. track arr[j] (e.g. in 
      // array {1, 5, 3} our best sequence 
      // would be {1, 3} with arr[j] = 3)
      int max_seq = Int32.MinValue;      
          
      // save arr[i]
      int store_min = min_num;   
          
      // Iterate from 1 to nums.size()
      for (int i = 1; i < nums.Length; i++) 
      {
        if (nums[i] == min_num)
          continue;
            
        else if (nums[i] < min_num) 
        {
          min_num = nums[i];
          continue;
        } 
            
        // this condition is only hit 
        // when current sequence size is 2
        else if (nums[i] < max_seq) {    
              
          // update best sequence max number 
          // to a smaller value 
          // (i.e. we've found a 
          // smaller value for arr[j])
          max_seq = nums[i];       
              
          // store best sequence start value 
          // i.e. arr[i]
          store_min = min_num;            
        } 
            
        // Increase best sequence length & 
        // save next number in our triplet
        else if (nums[i] > max_seq) 
        {    
          seq++;
              
          // We've found our arr[k]!
          // Print the output
          if (seq == 3) 
          {            
            Console.WriteLine("Triplet: " + store_min +
                               ", " + max_seq + ", " + nums[i]);
            return;
          }
          max_seq = nums[i];
        }
      }
          
      // No triplet found
      Console.Write("No such triplet found");
    }
      
  static void Main() {
    int[] nums = {1,2,-1,7,5};
  
    // Function Call
    find3Numbers(nums); 
  }
}
  
// This code is contributed by divyeshrabadiya07


Javascript


复杂性分析

  • 时间复杂度: O(n)。由于数组只遍历一次并且没有嵌套循环,因此时间复杂度将在 n 的数量级。
  • 辅助空间: O(n)。由于需要两个额外的数组来存储前一个较小元素和下一个较大元素的索引,因此所需的空间也将在 n 的数量级

参考:如何在线性时间内以递增的顺序查找数组中的 3 个数字并增加索引

方法二:

解决方案:首先找到两个元素 arr[i] & arr[j] 使得 arr[i] < arr[j]。然后找到大于 arr[j] 的第三个元素 arr[k]。
方法:我们可以用三个简单的术语来思考这个问题。

  1. 首先我们只需要找到两个元素 arr[i] < arr[j] 和 i < j。这可以在线性时间内完成,只需在数组范围内循环 1 次。例如,在跟踪 min 元素的同时,很容易找到任何大于它的后续元素。因此我们有我们的 arr[i] 和 arr[j]。
  2. 其次,考虑这个序列 - {3, 4, -1, 0, 2}。最初 min 为 3,arr[i] 为 3,arr[j] 为 4。在遍历数组时,我们可以轻松跟踪 min 并最终将其更新为 -1。我们还可以将 arr[i] 和 arr[j] 分别更新为较低的值,即 -1 和 0。
  3. 第三,一旦我们有了 arr[i] 和 arr[j] 的值,我们就可以立即开始监视同一循环中的后续元素是否存在 arr[k] > arr[j]。因此,我们可以在一次遍历数组中找到所有三个值 arr[i] < arr[j] < arr[k]。

算法:迭代数组的长度。跟踪分钟。一旦下一次迭代有一个大于 min 的元素,我们就找到了我们的 arr[j] 并且 min 将被保存为 arr[i]。继续迭代,直到找到大于 arr[j] 的元素 arr[k]。如果下一个元素的值较低,那么我们将 min、arr[i] 和 arr[j] 更新为这些较低的值,以便给我们找到 arr[k] 的最佳机会。

C++

// C++ Program for above approach
#include 
using namespace std;
  
// Function to find the triplet
void find3Numbers(vector& nums) 
{
    
  // If number of elements < 3
  // then no triplets are possible
  if (nums.size() < 3){
    cout << "No such triplet found";
    return;
  }
    
  // track best sequence length 
  // (not current sequence length)
  int seq = 1;        
    
  // min number in array
  int min_num = nums[0];  
    
  // least max number in best sequence 
  // i.e. track arr[j] (e.g. in 
  // array {1, 5, 3} our best sequence 
  // would be {1, 3} with arr[j] = 3)
  int max_seq = INT_MAX;      
    
  // save arr[i]
  int store_min = min_num;   
    
  // Iterate from 1 to nums.size()
  for (int i = 1; i < nums.size(); i++) 
  {
    if (nums[i] == min_num)
      continue;
      
    else if (nums[i] < min_num) 
    {
      min_num = nums[i];
      continue;
    } 
      
    // this condition is only hit 
    // when current sequence size is 2
    else if (nums[i] < max_seq) {    
        
      // update best sequence max number 
      // to a smaller value 
      // (i.e. we've found a 
      // smaller value for arr[j])
      max_seq = nums[i];       
        
      // store best sequence start value 
      // i.e. arr[i]
      store_min = min_num;            
    } 
      
    // Increase best sequence length & 
    // save next number in our triplet
    else if (nums[i] > max_seq) 
    {
      // We've found our arr[k]!
      // Print the output        
        cout << "Triplet: " << store_min << 
                 ", " << max_seq << ", " << 
                           nums[i] << endl;
        return;
    }
  }
    
  // No triplet found
  cout << "No such triplet found";
}
  
// Driver Code
int main() {
  vector nums {1,2,-1,7,5};
    
  // Function Call
  find3Numbers(nums);
}

Java

// Java Program for above approach
class Main 
{ 
    // Function to find the triplet
    public static void find3Numbers(int[] nums) 
    {
         
      // If number of elements < 3
      // then no triplets are possible
      if (nums.length < 3){
        System.out.print("No such triplet found");
        return;
      }
         
      // track best sequence length 
      // (not current sequence length)
      int seq = 1;        
         
      // min number in array
      int min_num = nums[0];  
         
      // least max number in best sequence 
      // i.e. track arr[j] (e.g. in 
      // array {1, 5, 3} our best sequence 
      // would be {1, 3} with arr[j] = 3)
      int max_seq = Integer.MIN_VALUE;      
         
      // save arr[i]
      int store_min = min_num;   
         
      // Iterate from 1 to nums.size()
      for (int i = 1; i < nums.length; i++) 
      {
        if (nums[i] == min_num)
          continue;
           
        else if (nums[i] < min_num) 
        {
          min_num = nums[i];
          continue;
        } 
           
        // this condition is only hit 
        // when current sequence size is 2
        else if (nums[i] < max_seq) {    
             
          // update best sequence max number 
          // to a smaller value 
          // (i.e. we've found a 
          // smaller value for arr[j])
          max_seq = nums[i];       
             
          // store best sequence start value 
          // i.e. arr[i]
          store_min = min_num;            
        } 
           
        // Increase best sequence length & 
        // save next number in our triplet
        else if (nums[i] > max_seq) 
        {    
          seq++;
             
          // We've found our arr[k]!
          // Print the output
          if (seq == 3) 
          {            
            System.out.println("Triplet: " + store_min +
                               ", " + max_seq + ", " + nums[i]);
            return;
          }
          max_seq = nums[i];
        }
      }
         
      // No triplet found
      System.out.print("No such triplet found");
    }
      
    // Driver program 
    public static void main(String[] args) 
    { 
        int[] nums = {1,2,-1,7,5};
     
        // Function Call
        find3Numbers(nums); 
    } 
} 
  
// This code is contributed by divyesh072019

Python3

# Python3 Program for above approach
import sys
  
# Function to find the triplet
def find3Numbers(nums):
    
  # If number of elements < 3
  # then no triplets are possible
  if (len(nums) < 3):
    print("No such triplet found", end = '')
    return
    
  # Track best sequence length 
  # (not current sequence length)
  seq = 1    
    
  # min number in array
  min_num = nums[0]
    
  # Least max number in best sequence 
  # i.e. track arr[j] (e.g. in 
  # array {1, 5, 3} our best sequence 
  # would be {1, 3} with arr[j] = 3)
  max_seq = -sys.maxsize - 1   
    
  # Save arr[i]
  store_min = min_num   
    
  # Iterate from 1 to nums.size()
  for i in range(1, len(nums)):
    if (nums[i] == min_num):
      continue
    elif (nums[i] < min_num):
      min_num = nums[i]
      continue
        
    # This condition is only hit 
    # when current sequence size is 2
    elif (nums[i] < max_seq):
        
      # Update best sequence max number 
      # to a smaller value 
      # (i.e. we've found a 
      # smaller value for arr[j])
      max_seq = nums[i]    
        
      # Store best sequence start value 
      # i.e. arr[i]
      store_min = min_num           
        
    # Increase best sequence length & 
    # save next number in our triplet
    elif (nums[i] > max_seq):
      if seq == 1:
        store_min = min_num
      seq += 1
        
      # We've found our arr[k]!
      # Print the output
      if (seq == 3):
        print("Triplet: " + str(store_min) +
              ", " + str(max_seq) + ", " +
                     str(nums[i]))
          
        return
        
      max_seq = nums[i]
     
  # No triplet found
  print("No such triplet found", end = '')
    
# Driver Code
if __name__=='__main__':
    
  nums = [ 1, 2, -1, 7, 5 ]
    
  # Function Call
  find3Numbers(nums)
  
# This code is contributed by rutvik_56

C#

// C# Program for above approach
using System;
class GFG {
      
    // Function to find the triplet
    static void find3Numbers(int[] nums) 
    {
          
      // If number of elements < 3
      // then no triplets are possible
      if (nums.Length < 3){
        Console.Write("No such triplet found");
        return;
      }
          
      // track best sequence length 
      // (not current sequence length)
      int seq = 1;        
          
      // min number in array
      int min_num = nums[0];  
          
      // least max number in best sequence 
      // i.e. track arr[j] (e.g. in 
      // array {1, 5, 3} our best sequence 
      // would be {1, 3} with arr[j] = 3)
      int max_seq = Int32.MinValue;      
          
      // save arr[i]
      int store_min = min_num;   
          
      // Iterate from 1 to nums.size()
      for (int i = 1; i < nums.Length; i++) 
      {
        if (nums[i] == min_num)
          continue;
            
        else if (nums[i] < min_num) 
        {
          min_num = nums[i];
          continue;
        } 
            
        // this condition is only hit 
        // when current sequence size is 2
        else if (nums[i] < max_seq) {    
              
          // update best sequence max number 
          // to a smaller value 
          // (i.e. we've found a 
          // smaller value for arr[j])
          max_seq = nums[i];       
              
          // store best sequence start value 
          // i.e. arr[i]
          store_min = min_num;            
        } 
            
        // Increase best sequence length & 
        // save next number in our triplet
        else if (nums[i] > max_seq) 
        {    
          seq++;
              
          // We've found our arr[k]!
          // Print the output
          if (seq == 3) 
          {            
            Console.WriteLine("Triplet: " + store_min +
                               ", " + max_seq + ", " + nums[i]);
            return;
          }
          max_seq = nums[i];
        }
      }
          
      // No triplet found
      Console.Write("No such triplet found");
    }
      
  static void Main() {
    int[] nums = {1,2,-1,7,5};
  
    // Function Call
    find3Numbers(nums); 
  }
}
  
// This code is contributed by divyeshrabadiya07

Javascript


输出
Triplet: 1, 2, 7

复杂性分析:

时间复杂度:O(n)。由于数组只遍历一次并且没有嵌套循环,因此时间复杂度将在 n 的数量级。
辅助空间:O(1)。

锻炼:

  1. 找到一个大小为 3 的子序列,使得 arr[i] < arr[j] > arr[k]。
  2. 在线性时间内找到大小为 4 的排序子序列