Open In App

Number of K-Spikes in Stock Price Array

Last Updated : 07 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given the changes to stock price over a period of time as an array of distinct integers, count the number of spikes in the stock price which are counted as K-Spikes.

A K-Spike is an element that satisfies both the following conditions:

  • There are at least K elements from indices (0, i-1) that are less than the price[i].
  • There are at least K elements from indices (i+1, n-1) that are less than the price[i].

Examples:

Input: price = [1, 2, 8, 5, 3, 4], K = 2
Output: 2
Explanation: There are 2 K-Spikes:
• 8 at index 2 has (1, 2) to the left and (5, 3, 4) to the right that are less than 8.
• 5 at index 3 has (1, 2) to the left and (3, 4) to the right that are less than 5.

Input: price = [7, 2, 3, 9, 7, 4], K = 3
Output: 0
Explanation: There is no K-spike possible for any i. For element 9 there are at least 3 elements smaller than 9 on the left side but there are only 2 elements that are smaller than 9 on the right side.

Naive approach: The basic way to solve the problem is as follows:

The idea is to check for every element of the price array whether it is a K-spike or not.

  • To check we calculate the number of elements that are smaller than prices[i] in the range [0 …… i-1]
  • Calculate the number of elements that are smaller than the price[i] in the range[i+1 …… N] by again traversing using loops
  • After that if the given condition is satisfied then the price[i] is K-spike then we increment our answer.


Python
def countKSpikes(price, K):
    n = len(price)
    # Initialize left and right arrays to store the count of smaller elements
    left = [0] * n
    right = [0] * n

    # Preprocess left array
    for i in range(1, n):
        count = 0
        for j in range(i):
            if price[j] < price[i]:
                count += 1
        left[i] = count

    # Preprocess right array
    for i in range(n - 2, -1, -1):
        count = 0
        for j in range(i + 1, n):
            if price[j] < price[i]:
                count += 1
        right[i] = count

    # Count K-spikes
    spike_count = 0
    for i in range(n):
        if left[i] >= K and right[i] >= K:
            spike_count += 1

    return spike_count


# Example usage:
price1 = [1, 2, 8, 5, 3, 4]
K1 = 2
print("Number of K-spikes:", countKSpikes(price1, K1))  # Output: 2

price2 = [7, 2, 3, 9, 7, 4]
K2 = 3
print("Number of K-spikes:", countKSpikes(price2, K2))  # Output: 0

Output
Number of K-spikes: 2
Number of K-spikes: 0


Time complexity: O(N2)
Auxillary space: O(1)

Efficient approach: To solve the problem follow the below idea:

In the naive approach we have traversed the array again for finding count of smaller elements till i-1 or from i+1, but how about precalculating the number of elements that are smaller than price[i] in range[0…… i-1] and also in range[i+1…..N) and storing them in an prefix and suffix array respectively.

Follow the steps to solve the problem:

  • We construct two array’s prefix and suffix, prefix[i] denotes number of elements that are smaller than price[i] in [0……i-1] and suffix[i] denotes the number of elements that are smaller than price[i] in [i+1 …… N).
  • To construct prefix array we maintain a ordered set(Policy based data structure) in which elements till index i-1 already present in set so we can find the position of price[i] in ordered set by using order_of_key function which gives number of items strictly smaller than price[i] then we just put this value at prefix[i] and at last we push price[i] in set.
  • To construct suffix array we traverse the price array backwards and do the similar thing that we have done for prefix array.
  • Now we have prefix and suffix array in our hand then we traverse the price aray and check if both prefix[i] and suffix[i] are at least K then we increment our answer.

Below is the implementation of the above approach:

C++
// C++ code for the above approach:
#include &lt;bits/stdc++.h&gt;
#include &lt;ext/pb_ds/assoc_container.hpp&gt;
#include &lt;ext/pb_ds/tree_policy.hpp&gt;

using namespace std;
using namespace __gnu_pbds;

template &lt;typename T&gt;
using pbds = tree&lt;T, null_type, less&lt;T&gt;, rb_tree_tag,
                  tree_order_statistics_node_update&gt;;

// Function to calculate the number of
// spikes in price array
int CalculateNumberOfKSpikes(vector&lt;int&gt;&amp; price, int k)
{
    int n = price.size();

    // Decalare ordered set
    pbds&lt;int&gt; st1, st2;

    // Initialize a variable for storing our
    // number of K-spikes
    int countOfKspikes = 0;

    // Declaring prefix and suffix array where
    // prefix[i] denotes number of elements
    // that are smaller than price[i] in
    // [0......i-1] and suffix[i] denotes the
    // number of elements that are smaller than
    // price[i] in [i+1 ...... N).
    vector&lt;int&gt; prefix(n + 1, 0), suffix(n + 1, 0);
    for (int i = 0; i &lt; n; i++) {

        // Calculate the number of elements that
        // are smaller than price[i] using
        // order_of_key function
        prefix[i] = st1.order_of_key(price[i]);

        // Insert current price[i] to contribute in
        // next iteration
        st1.insert(price[i]);
    }

    for (int i = n - 1; i &gt;= 0; i--) {

        // Calculate the number of elements that
        // are smaller than price[i] using
        // order_of_key function
        suffix[i] = st2.order_of_key(price[i]);

        // Insert current price[i] to contribute
        // in next iteration
        st2.insert(price[i]);
    }

    for (int i = 0; i &lt; n; i++) {

        // If prefix and suffix are atleast K than
        // current element is k-spike
        if (prefix[i] &gt;= k &amp;&amp; suffix[i] &gt;= k) {
            countOfKspikes++;
        }
    }
    return countOfKspikes;
}

// Drivers code
int main()
{
    vector&lt;int&gt; price = { 1, 2, 8, 5, 3, 4 };
    int k = 2;

    int countOfKspikes = CalculateNumberOfKSpikes(price, k);

    // Function Call
    cout &lt;&lt; countOfKspikes;
    return 0;
}
Java
import java.util.TreeSet;

public class Main {
    // Function to calculate the number of spikes in price array
    static int calculateNumberOfKSpikes(int[] price, int k) {
        int n = price.length;

        // Declare ordered sets
        TreeSet<Integer> st1 = new TreeSet<>();
        TreeSet<Integer> st2 = new TreeSet<>();

        // Initialize a variable for storing our number of K-spikes
        int countOfKSpikes = 0;

        // Declaring prefix and suffix arrays where
        // prefix[i] denotes the number of elements
        // that are smaller than price[i] in
        // [0......i-1] and suffix[i] denotes the
        // number of elements that are smaller than
        // price[i] in [i+1 ...... N).
        int[] prefix = new int[n + 1];
        int[] suffix = new int[n + 1];

        for (int i = 0; i < n; i++) {
            // Calculate the number of elements that
            // are smaller than price[i] using
            // lower() function
            prefix[i] = st1.headSet(price[i]).size();

            // Insert current price[i] to contribute in
            // the next iteration
            st1.add(price[i]);
        }

        for (int i = n - 1; i >= 0; i--) {
            // Calculate the number of elements that
            // are smaller than price[i] using
            // lower() function
            suffix[i] = st2.headSet(price[i]).size();

            // Insert current price[i] to contribute
            // in the next iteration
            st2.add(price[i]);
        }

        for (int i = 0; i < n; i++) {
            // If prefix and suffix are at least K, then
            // the current element is a K-spike
            if (prefix[i] >= k && suffix[i] >= k) {
                countOfKSpikes++;
            }
        }

        return countOfKSpikes;
    }

    // Driver code
    public static void main(String[] args) {
        int[] price = {1, 2, 8, 5, 3, 4};
        int k = 2;

        int countOfKSpikes = calculateNumberOfKSpikes(price, k);

        // Function Call
        System.out.println(countOfKSpikes);
    }
}
Python
def calculate_number_of_k_spikes(price, k):
    n = len(price)

    # Declare ordered sets
    st1 = set()
    st2 = set()

    # Initialize a variable for storing the number of K-spikes
    count_of_k_spikes = 0

    # Declaring prefix and suffix arrays where
    # prefix[i] denotes the number of elements
    # that are smaller than price[i] in
    # [0......i-1] and suffix[i] denotes the
    # number of elements that are smaller than
    # price[i] in [i+1 ...... N).
    prefix = [0] * (n + 1)
    suffix = [0] * (n + 1)

    for i in range(n):
        # Calculate the number of elements that
        # are smaller than price[i] using set operations
        prefix[i] = len([x for x in st1 if x < price[i]])

        # Insert current price[i] to contribute in
        # the next iteration
        st1.add(price[i])

    for i in range(n - 1, -1, -1):
        # Calculate the number of elements that
        # are smaller than price[i] using set operations
        suffix[i] = len([x for x in st2 if x < price[i]])

        # Insert current price[i] to contribute
        # in the next iteration
        st2.add(price[i])

    for i in range(n):
        # If prefix and suffix are at least K, then
        # the current element is a K-spike
        if prefix[i] >= k and suffix[i] >= k:
            count_of_k_spikes += 1

    return count_of_k_spikes

# Driver code
if __name__ == "__main__":
    price = [1, 2, 8, 5, 3, 4]
    k = 2

    count_of_k_spikes = calculate_number_of_k_spikes(price, k)

    # Function Call
    print(count_of_k_spikes)
#This Code is Contributed by chinmaya121221
C#
using System;
using System.Collections.Generic;

public class MainClass
{
    // Function to calculate the number of spikes in price array
    static int CalculateNumberOfKSpikes(int[] price, int k)
    {
        int n = price.Length;

        // Declare ordered sets
        SortedSet<int> st1 = new SortedSet<int>();
        SortedSet<int> st2 = new SortedSet<int>();

        // Initialize a variable for storing our number of K-spikes
        int countOfKSpikes = 0;

        // Declaring prefix and suffix arrays where
        // prefix[i] denotes the number of elements
        // that are smaller than price[i] in
        // [0......i-1] and suffix[i] denotes the
        // number of elements that are smaller than
        // price[i] in [i+1 ...... N).
        int[] prefix = new int[n + 1];
        int[] suffix = new int[n + 1];

        for (int i = 0; i < n; i++)
        {
            // Calculate the number of elements that
            // are smaller than price[i] using
            // headSet() function
            prefix[i] = st1.GetViewBetween(int.MinValue, price[i]).Count;

            // Insert current price[i] to contribute in
            // the next iteration
            st1.Add(price[i]);
        }

        for (int i = n - 1; i >= 0; i--)
        {
            // Calculate the number of elements that
            // are smaller than price[i] using
            // headSet() function
            suffix[i] = st2.GetViewBetween(int.MinValue, price[i]).Count;

            // Insert current price[i] to contribute
            // in the next iteration
            st2.Add(price[i]);
        }

        for (int i = 0; i < n; i++)
        {
            // If prefix and suffix are at least K, then
            // the current element is a K-spike
            if (prefix[i] >= k && suffix[i] >= k)
            {
                countOfKSpikes++;
            }
        }

        return countOfKSpikes;
    }

    // Driver code
    public static void Main(string[] args)
    {
        int[] price = { 1, 2, 8, 5, 3, 4 };
        int k = 2;

        int countOfKSpikes = CalculateNumberOfKSpikes(price, k);

        // Function Call
        Console.WriteLine(countOfKSpikes);
    }
}

// This code is contributed by akshitaguprzj3
Javascript
// Function to calculate the number of K-spikes in the given array
function calculateNumberOfKSpikes(price, k) {
    const n = price.length;

    // Declare sets for prefix and suffix
    const st1 = new Set();
    const st2 = new Set();

    // Initialize a variable for storing the number of K-spikes
    let countOfKSpikes = 0;

    // Arrays to store prefix and suffix counts
    const prefix = new Array(n + 1).fill(0);
    const suffix = new Array(n + 1).fill(0);

    // Calculate prefix counts
    for (let i = 0; i < n; i++) {
        prefix[i] = [...st1].filter(x => x < price[i]).length;

        // Insert current price[i] to contribute in the next iteration
        st1.add(price[i]);
    }

    // Clear sets for suffix calculation
    st1.clear();

    // Calculate suffix counts
    for (let i = n - 1; i >= 0; i--) {
        suffix[i] = [...st2].filter(x => x < price[i]).length;

        // Insert current price[i] to contribute in the next iteration
        st2.add(price[i]);
    }

    // Check for K-spikes
    for (let i = 0; i < n; i++) {
        // If prefix and suffix are at least K, then the current element is a K-spike
        if (prefix[i] >= k && suffix[i] >= k) {
            countOfKSpikes++;
        }
    }

    return countOfKSpikes;
}

// Driver code
const price = [1, 2, 8, 5, 3, 4];
const k = 2;

// Function Call
const countOfKSpikes = calculateNumberOfKSpikes(price, k);
console.log(countOfKSpikes);

Output
2














Time Complexity: O(N*logN)
Auxillary space: O(N), where N is the size of the array.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads