📌  相关文章
📜  通过将每个元素减少一个下一个较小的元素来修改给定数组

📅  最后修改于: 2021-05-13 22:19:21             🧑  作者: Mango

给定长度为N的数组arr [] ,任务是通过将给定数组的每个元素替换为其下一个较小的元素(如果可能)来修改给定数组。将修改后的数组打印为所需答案。

例子:

天真的方法:最简单的方法是遍历数组,对于每个元素,遍历数组之后的其余元素,并检查是否存在更小的元素。如果找到该元素,则将该元素减少为所获得的第一个较小的元素。

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

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to print the final array
// after reducing each array element
// by its next smaller element
void printFinalPrices(vector& arr)
{
    // Stores the resultant array
    vector ans;
 
    // Traverse the array
    for (int i = 0; i < arr.size(); i++) {
        int flag = 1;
        for (int j = i + 1; j < arr.size(); j++) {
 
            // If a smaller element is found
            if (arr[j] <= arr[i]) {
 
                // Reduce current element by
                // next smaller element
                ans.push_back(arr[i] - arr[j]);
                flag = 0;
                break;
            }
        }
 
        // If no smaller element is found
        if (flag == 1)
            ans.push_back(arr[i]);
    }
 
    // Print the answer
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
}
 
// Driver Code
int main()
{
    // Given array
    vector arr = { 8, 4, 6, 2, 3 };
 
    // Function Call
    printFinalPrices(arr);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Function to print the final array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Stores the resultant array
    ArrayList ans = new ArrayList();
     
    // Traverse the array
    for(int i = 0; i < arr.length; i++)
    {
        int flag = 1;
        for(int j = i + 1; j < arr.length; j++)
        {
             
            // If a smaller element is found
            if (arr[j] <= arr[i])
            {
                 
                // Reduce current element by
                // next smaller element
                ans.add(arr[i] - arr[j]);
                flag = 0;
                break;
            }
        }
    
        // If no smaller element is found
        if (flag == 1)
            ans.add(arr[i]);
    }
    
    // Print the answer
    for(int i = 0; i < ans.size(); i++)
        System.out.print(ans.get(i) + " ");
} 
  
// Driver Code
public static void main(String[] args)
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
   
    // Function Call
    printFinalPrices(arr);
}
}
 
// This code is contributed by code_hunt


Python3
# Python3 program for the above approach
 
# Function to print the final array
# after reducing each array element
# by its next smaller element
def printFinalarr(arr):
 
  # Stores resultant array
    ans = []
 
    # Traverse the given array
    for i in range(len(arr)):
        flag = 1
        for j in range(i + 1, len(arr)):
             
            # If a smaller element is found
            if arr[j] <= arr[i]:
 
                # Reduce current element by
                # next smaller element
                ans.append(arr[i] - arr[j])
                flag = 0
                break
        if flag:
 
            # If no smaller element is found
            ans.append(arr[i])
 
    # Print the final array
    for k in range(len(ans)):
        print(ans[k], end =' ')
 
 
# Driver Code
if __name__ == '__main__':
 
  # Given array
    arr = [8, 4, 6, 2, 3]
 
  # Function call
    printFinalarr(arr)


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to print the final array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Stores the resultant array
    List ans = new List();
   
    // Traverse the array
    for(int i = 0; i < arr.Length; i++)
    {
        int flag = 1;
        for(int j = i + 1; j < arr.Length; j++)
        {
             
            // If a smaller element is found
            if (arr[j] <= arr[i])
            {
                 
                // Reduce current element by
                // next smaller element
                ans.Add(arr[i] - arr[j]);
                flag = 0;
                break;
            }
        }
   
        // If no smaller element is found
        if (flag == 1)
            ans.Add(arr[i]);
    }
   
    // Print the answer
    for(int i = 0; i < ans.Count; i++)
        Console.Write(ans[i] + " ");
} 
 
// Driver code
static void Main()
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
  
    // Function Call
    printFinalPrices(arr);
}
}
 
// This code is contributed by divyeshrabadiya07


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to print the final array
// after reducing each array element
// by its next smaller element
void printFinalPrices(vector& arr)
{
 
    // Initialize stack
    stack minStk;
 
    // Array size
    int n = arr.size();
 
    // To store the corresponding element
    vector reduce(n, 0);
    for (int i = n - 1; i >= 0; i--) {
 
        // If stack is not empty
        if (!minStk.empty()) {
 
            // If top element is smaller
            // than the current element
            if (minStk.top() <= arr[i]) {
                reduce[i] = minStk.top();
            }
            else {
 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (!minStk.empty()
                       && (minStk.top() > arr[i])) {
                    minStk.pop();
                }
 
                // If stack is not epty
                if (!minStk.empty()) {
                    reduce[i] = minStk.top();
                }
            }
        }
 
        // Push current element
        minStk.push(arr[i]);
    }
 
    // Print the final array
    for (int i = 0; i < n; i++)
        cout << arr[i] - reduce[i] << " ";
}
 
// Driver Code
int main()
{
 
    // Given array
    vector arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to print the final array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Initialize stack
    Stack minStk = new Stack<>();
     
    // Array size
    int n = arr.length;
 
    // To store the corresponding element
    int[] reduce = new int[n];
    for(int i = n - 1; i >= 0; i--)
    {
         
        // If stack is not empty
        if (!minStk.isEmpty())
        {
             
            // If top element is smaller
            // than the current element
            if (minStk.peek() <= arr[i])
            {
                reduce[i] = minStk.peek();
            }
            else
            {
                 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (!minStk.isEmpty() &&
                       (minStk.peek() > arr[i]))
                {
                    minStk.pop();
                }
 
                // If stack is not epty
                if (!minStk.isEmpty())
                {
                    reduce[i] = minStk.peek();
                }
            }
        }
 
        // Push current element
        minStk.add(arr[i]);
    }
 
    // Print the final array
    for(int i = 0; i < n; i++)
        System.out.print(arr[i] - reduce[i] + " ");
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program for the above approach
 
# Function to print the final array
# after reducing each array element
# by its next smaller element
def printFinalPrices(arr):
 
  # Initialize stack
    minStk = []
 
    # To store the corresponding element
    reduce = [0] * len(arr)
    for i in range(len(arr) - 1, -1, -1):
 
       # If stack is not empty
        if minStk:
 
            # If top element is smaller
            # than the current element
            if minStk[-1] <= arr[i]:
                reduce[i] = minStk[-1]
            else:
 
              # Keep popping until stack is empty
                # or top element is greater than
                # the current element
                while minStk and minStk[-1] > arr[i]:
                    minStk.pop()
 
                if minStk:
 
                  # Corresponding elements
                    reduce[i] = minStk[-1]
 
        # Push current element
        minStk.append(arr[i])
 
    # Final array
    for i in range(len(arr)):
        print(arr[i] - reduce[i], end =' ')
 
 
# Driver Code
if __name__ == '__main__':
 
  # Given array
    arr = [8, 4, 6, 2, 3]
 
   # Function Call
    printFinalPrices(arr)


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Function to print the readonly array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Initialize stack
    Stack minStk = new Stack();
     
    // Array size
    int n = arr.Length;
 
    // To store the corresponding element
    int[] reduce = new int[n];
    for(int i = n - 1; i >= 0; i--)
    {
         
        // If stack is not empty
        if (minStk.Count != 0)
        {
             
            // If top element is smaller
            // than the current element
            if (minStk.Peek() <= arr[i])
            {
                reduce[i] = minStk.Peek();
            }
            else
            {
                 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (minStk.Count != 0 &&
                       (minStk.Peek() > arr[i]))
                {
                    minStk.Pop();
                }
 
                // If stack is not epty
                if (minStk.Count != 0)
                {
                    reduce[i] = minStk.Peek();
                }
            }
        }
 
        // Push current element
        minStk.Push(arr[i]);
    }
 
    // Print the readonly array
    for(int i = 0; i < n; i++)
        Console.Write(arr[i] - reduce[i] + " ");
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
}
}
 
// This code contributed by shikhasingrajput


输出:
4 2 4 2 3

高效的方法:为了优化上述方法,其思想是使用Stack数据结构。请按照以下步骤解决问题:

  1. 初始化堆栈 和大小为N的数组ans []存储结果数组。
  2. 遍历索引i = N – 1到0的给定数组。
  3. 如果堆栈为空,则将当前元素arr [i]推到堆栈顶部。
  4. 否则,如果当前元素大于堆栈顶部的元素,则将其推入堆栈,然后从堆栈中删除元素,直到堆栈变空或找到小于或等于arr [i]的元素。此后,如果堆栈不为空,则设置ans [i] = arr [i] –堆栈的顶部元素,然后将其从堆栈中删除。
  5. 否则,从堆栈中删除顶部元素,并将ans [i]设置为等于堆栈中的顶部元素,然后从堆栈中将其删除。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to print the final array
// after reducing each array element
// by its next smaller element
void printFinalPrices(vector& arr)
{
 
    // Initialize stack
    stack minStk;
 
    // Array size
    int n = arr.size();
 
    // To store the corresponding element
    vector reduce(n, 0);
    for (int i = n - 1; i >= 0; i--) {
 
        // If stack is not empty
        if (!minStk.empty()) {
 
            // If top element is smaller
            // than the current element
            if (minStk.top() <= arr[i]) {
                reduce[i] = minStk.top();
            }
            else {
 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (!minStk.empty()
                       && (minStk.top() > arr[i])) {
                    minStk.pop();
                }
 
                // If stack is not epty
                if (!minStk.empty()) {
                    reduce[i] = minStk.top();
                }
            }
        }
 
        // Push current element
        minStk.push(arr[i]);
    }
 
    // Print the final array
    for (int i = 0; i < n; i++)
        cout << arr[i] - reduce[i] << " ";
}
 
// Driver Code
int main()
{
 
    // Given array
    vector arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to print the final array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Initialize stack
    Stack minStk = new Stack<>();
     
    // Array size
    int n = arr.length;
 
    // To store the corresponding element
    int[] reduce = new int[n];
    for(int i = n - 1; i >= 0; i--)
    {
         
        // If stack is not empty
        if (!minStk.isEmpty())
        {
             
            // If top element is smaller
            // than the current element
            if (minStk.peek() <= arr[i])
            {
                reduce[i] = minStk.peek();
            }
            else
            {
                 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (!minStk.isEmpty() &&
                       (minStk.peek() > arr[i]))
                {
                    minStk.pop();
                }
 
                // If stack is not epty
                if (!minStk.isEmpty())
                {
                    reduce[i] = minStk.peek();
                }
            }
        }
 
        // Push current element
        minStk.add(arr[i]);
    }
 
    // Print the final array
    for(int i = 0; i < n; i++)
        System.out.print(arr[i] - reduce[i] + " ");
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 program for the above approach
 
# Function to print the final array
# after reducing each array element
# by its next smaller element
def printFinalPrices(arr):
 
  # Initialize stack
    minStk = []
 
    # To store the corresponding element
    reduce = [0] * len(arr)
    for i in range(len(arr) - 1, -1, -1):
 
       # If stack is not empty
        if minStk:
 
            # If top element is smaller
            # than the current element
            if minStk[-1] <= arr[i]:
                reduce[i] = minStk[-1]
            else:
 
              # Keep popping until stack is empty
                # or top element is greater than
                # the current element
                while minStk and minStk[-1] > arr[i]:
                    minStk.pop()
 
                if minStk:
 
                  # Corresponding elements
                    reduce[i] = minStk[-1]
 
        # Push current element
        minStk.append(arr[i])
 
    # Final array
    for i in range(len(arr)):
        print(arr[i] - reduce[i], end =' ')
 
 
# Driver Code
if __name__ == '__main__':
 
  # Given array
    arr = [8, 4, 6, 2, 3]
 
   # Function Call
    printFinalPrices(arr)

C#

// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Function to print the readonly array
// after reducing each array element
// by its next smaller element
static void printFinalPrices(int[] arr)
{
     
    // Initialize stack
    Stack minStk = new Stack();
     
    // Array size
    int n = arr.Length;
 
    // To store the corresponding element
    int[] reduce = new int[n];
    for(int i = n - 1; i >= 0; i--)
    {
         
        // If stack is not empty
        if (minStk.Count != 0)
        {
             
            // If top element is smaller
            // than the current element
            if (minStk.Peek() <= arr[i])
            {
                reduce[i] = minStk.Peek();
            }
            else
            {
                 
                // Keep popping until stack is empty
                // or top element is greater than
                // the current element
                while (minStk.Count != 0 &&
                       (minStk.Peek() > arr[i]))
                {
                    minStk.Pop();
                }
 
                // If stack is not epty
                if (minStk.Count != 0)
                {
                    reduce[i] = minStk.Peek();
                }
            }
        }
 
        // Push current element
        minStk.Push(arr[i]);
    }
 
    // Print the readonly array
    for(int i = 0; i < n; i++)
        Console.Write(arr[i] - reduce[i] + " ");
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given array
    int[] arr = { 8, 4, 6, 2, 3 };
 
    // Function call
    printFinalPrices(arr);
}
}
 
// This code contributed by shikhasingrajput
输出:
4 2 4 2 3

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