comments | difficulty | edit_url | tags | ||||
---|---|---|---|---|---|---|---|
true |
Medium |
|
You are given an integer array nums
.
Return the length of the longest semi-decreasing subarray of nums
, and 0
if there are no such subarrays.
- A subarray is a contiguous non-empty sequence of elements within an array.
- A non-empty array is semi-decreasing if its first element is strictly greater than its last element.
Example 1:
Input: nums = [7,6,5,4,3,2,1,6,10,11] Output: 8 Explanation: Take the subarray [7,6,5,4,3,2,1,6]. The first element is 7 and the last one is 6 so the condition is met. Hence, the answer would be the length of the subarray or 8. It can be shown that there aren't any subarrays with the given condition with a length greater than 8.
Example 2:
Input: nums = [57,55,50,60,61,58,63,59,64,60,63] Output: 6 Explanation: Take the subarray [61,58,63,59,64,60]. The first element is 61 and the last one is 60 so the condition is met. Hence, the answer would be the length of the subarray or 6. It can be shown that there aren't any subarrays with the given condition with a length greater than 6.
Example 3:
Input: nums = [1,2,3,4] Output: 0 Explanation: Since there are no semi-decreasing subarrays in the given array, the answer is 0.
Constraints:
1 <= nums.length <= 105
-109 <= nums[i] <= 109
The problem is essentially finding the maximum length of the inverse pairs. We can use a hash table
Next, we traverse the keys of the hash table in descending order of the numbers. We maintain a number
The time complexity is
class Solution:
def maxSubarrayLength(self, nums: List[int]) -> int:
d = defaultdict(list)
for i, x in enumerate(nums):
d[x].append(i)
ans, k = 0, inf
for x in sorted(d, reverse=True):
ans = max(ans, d[x][-1] - k + 1)
k = min(k, d[x][0])
return ans
class Solution {
public int maxSubarrayLength(int[] nums) {
TreeMap<Integer, List<Integer>> d = new TreeMap<>(Comparator.reverseOrder());
for (int i = 0; i < nums.length; ++i) {
d.computeIfAbsent(nums[i], k -> new ArrayList<>()).add(i);
}
int ans = 0, k = 1 << 30;
for (List<Integer> idx : d.values()) {
ans = Math.max(ans, idx.get(idx.size() - 1) - k + 1);
k = Math.min(k, idx.get(0));
}
return ans;
}
}
class Solution {
public:
int maxSubarrayLength(vector<int>& nums) {
map<int, vector<int>, greater<int>> d;
for (int i = 0; i < nums.size(); ++i) {
d[nums[i]].push_back(i);
}
int ans = 0, k = 1 << 30;
for (auto& [_, idx] : d) {
ans = max(ans, idx.back() - k + 1);
k = min(k, idx[0]);
}
return ans;
}
};
func maxSubarrayLength(nums []int) (ans int) {
d := map[int][]int{}
for i, x := range nums {
d[x] = append(d[x], i)
}
keys := []int{}
for x := range d {
keys = append(keys, x)
}
sort.Slice(keys, func(i, j int) bool { return keys[i] > keys[j] })
k := 1 << 30
for _, x := range keys {
idx := d[x]
ans = max(ans, idx[len(idx)-1]-k+1)
k = min(k, idx[0])
}
return ans
}
function maxSubarrayLength(nums: number[]): number {
const d: Map<number, number[]> = new Map();
for (let i = 0; i < nums.length; ++i) {
if (!d.has(nums[i])) {
d.set(nums[i], []);
}
d.get(nums[i])!.push(i);
}
const keys = Array.from(d.keys()).sort((a, b) => b - a);
let ans = 0;
let k = Infinity;
for (const x of keys) {
const idx = d.get(x)!;
ans = Math.max(ans, idx.at(-1) - k + 1);
k = Math.min(k, idx[0]);
}
return ans;
}