11"""
2- Implement the function to find the kth Next Greatest Element (NGE), if it exists, for all elements.
3- Idea comes from my blog: https://starsexpress.github.io/SkyHorse/docs/stack/2454_hard/second_next_greater
2+ Implement the function to find kth Next Greatest Element (NGE) for all elements.
3+ Idea comes from my blog:
4+ https://starsexpress.github.io/SkyHorse/docs/stack/2454_hard/second_next_greater
45"""
56
6- from __future__ import annotations
7-
8-
97test_k = 10
10- test_array = [ value for value in range (10000 )]
8+ test_array = list ( range (10000 ))
119expected_answers = [value + test_k for value in range (10000 - test_k )] + [None ] * test_k
1210
1311
1412def find_kth_next_greater_element (
15- array : list [int | float ], k : int
13+ array : list [int | float ], kth_ord : int
1614) -> list [int | float | None ]:
1715 """
1816 Efficient general method to seek the kth NGE for all elements.
@@ -29,55 +27,55 @@ def find_kth_next_greater_element(
2927 However, if k >= n, all elements won't find their respective kth NGE.
3028 As a result, worst case time complexity is O(n^2) when k < n but k ≈ n.
3129
32- Space complexity: O(n), since at any point, an element can only stay in one of these k stacks.
30+ Space complexity: O(n), since at any point, an element is only in one of k stacks.
3331
3432 Args:
3533 array (list[int | float]): A list for which the kth NGE is computed.
3634 A mix of integers and floats in list is allowed.
3735
38- k (int): Ordinal of the NGE to find. k must be a positive integer.
36+ kth_ord (int): Ordinal of the NGE to find. k must be a positive integer.
3937
4038 Returns:
4139 A list containing each element's kth NGE. If an element can't find its kth NGE,
4240 None, instead of -1, is put as its entry, because input array might have -1.
4341
4442 Example:
45- >>> find_kth_next_greater_element([1, 2, 3, 4, 5, 6, 7 ], 3) == [4, 5, 6, 7 , None, None, None]
43+ >>> find_kth_next_greater_element([1, 2, 3, 4, 5, 6], 3) == [4, 5, 6, None, None, None]
4644 True
47- >>> find_kth_next_greater_element([2.5, 1.9, 4.3, 3.5, 6.0, 5.8 ], 1) == [4.3, 4.3, 6.0, 6.0, None , None]
45+ >>> find_kth_next_greater_element([2.5, 1.9, 4.3, 3.5, 6.0], 1) == [4.3, 4.3, 6.0, 6.0, None]
4846 True
49- >>> find_kth_next_greater_element([value for value in range(1000)] , 1000) == [None] * 1000
47+ >>> find_kth_next_greater_element(list( range(1000)) , 1000) == [None] * 1000
5048 True
5149 >>> find_kth_next_greater_element(test_array, test_k) == expected_answers
5250 True
5351 """
54- if not isinstance (k , int ) or k < 1 :
52+ if not isinstance (kth_ord , int ) or kth_ord < 1 :
5553 raise ValueError ("k must be a positive integer." )
5654
5755 kth_next_greater_elements : list [int | float | None ] = [None ] * len (array )
58- if k >= len (array ): # Trivial cases: nobody can have kth NGE.
56+ if kth_ord >= len (array ): # Trivial cases: nobody can have kth NGE.
5957 return kth_next_greater_elements
6058
6159 # For 1 <= j <= k, the jth stack is at the jth idx of stacks list.
6260 # stacks[0]: a transporter that transfer entries between stacks.
6361 # Each stack's entry is a tuple of (element, idx).
64- stacks : list [list [tuple [int | float , int ]]] = [[] for _ in range (k + 1 )]
62+ stacks : list [list [tuple [int | float , int ]]] = [[] for _ in range (kth_ord + 1 )]
6563
6664 for idx , element in enumerate (array ):
6765 # From kth stack to answer found.
68- while stacks [k ] and stacks [k ][- 1 ][0 ] < element :
69- _ , prev_idx = stacks [k ].pop ()
66+ while stacks [kth_ord ] and stacks [kth_ord ][- 1 ][0 ] < element :
67+ _ , prev_idx = stacks [kth_ord ].pop ()
7068 kth_next_greater_elements [prev_idx ] = element
7169
72- for stack_ord in range (k - 1 , 0 , - 1 ): # From (k - 1)th to 1st stack.
70+ for stack_ord in range (kth_ord - 1 , 0 , - 1 ): # From (k - 1)th to 1st stack.
7371 while stacks [stack_ord ] and stacks [stack_ord ][- 1 ][0 ] < element :
7472 stacks [0 ].append (stacks [stack_ord ].pop ())
7573
7674 while stacks [0 ]: # Move to the next ordered stack.
7775 stacks [stack_ord + 1 ].append (stacks [0 ].pop ())
7876
7977 unvisited_elements_count = len (array ) - 1 - idx
80- if unvisited_elements_count >= k : # Element has a chance to find kth NGE.
78+ if unvisited_elements_count >= kth_ord : # Element has a chance to find kth NGE.
8179 stacks [1 ].append ((element , idx )) # Always join 1st stack to begin search.
8280
8381 return kth_next_greater_elements
0 commit comments