LeetCode-1438. 절대 차이가있는 최장 연속 하위 배열 ... [중간]-분석 및 코드 (자바)

LeetCode-1438. 절대 차이가 한계보다 작거나 같은 가장 긴 연속 서브 어레이 [절대 차이가 한계보다 작거나 같은 가장 긴 연속 서브 어레이] [중간]-분석 및 코드 [Java]

1. 주제

정수 배열 nums와 제한을 나타내는 정수 제한이 주어지면 가장 긴 연속 하위 배열의 길이를 반환하십시오. 하위 배열에서 두 요소 간의 절대 차이는 제한보다 작거나 같아야합니다.
조건을 충족하는 하위 배열이 없으면 0이 반환됩니다.

예 1 :

输入:nums = [8,2,4,7], limit = 4
输出:2 
解释:所有子数组如下:
[8] 最大绝对差 |8-8| = 0 <= 4.
[8,2] 最大绝对差 |8-2| = 6 > 4. 
[8,2,4] 最大绝对差 |8-2| = 6 > 4.
[8,2,4,7] 最大绝对差 |8-2| = 6 > 4.
[2] 最大绝对差 |2-2| = 0 <= 4.
[2,4] 最大绝对差 |2-4| = 2 <= 4.
[2,4,7] 最大绝对差 |2-7| = 5 > 4.
[4] 最大绝对差 |4-4| = 0 <= 4.
[4,7] 最大绝对差 |4-7| = 3 <= 4.
[7] 最大绝对差 |7-7| = 0 <= 4. 
因此,满足题意的最长子数组的长度为 2 。

예 2 :

输入:nums = [10,1,2,4,7,2], limit = 5
输出:4 
解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。

예 3 :

输入:nums = [4,2,2,2,4,4,2,2], limit = 0
输出:3

신속한:

  • 1 <= nums.length <= 10 ^ 5
  • 1 <= nums [i] <= 10 ^ 9
  • 0 <= 제한 <= 10 ^ 9

Source : stay button (LeetCode)
link : https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit
copyright of the collar button all 네트워크. 상업적 재판의 경우 공식 승인에 문의하고 비상업적 재판의 경우 출처를 표시하십시오.

둘째, 분석 및 코드

1. 슬라이딩 윈도우 + 데크

(1) 생각

요소의 최대 절대 값 차이가 한계를 초과하지 않는 슬라이딩 윈도우를 설계하면 슬라이딩 프로세스에서 간격의 최대 길이가 솔루션입니다.
O (n) 복잡도 내에서 슬라이딩 윈도우의 최대 값과 최소값을 계산하기 위해 윈도우 슬라이딩 프로세스 동안 실시간으로 대기열을 유지하도록 데크를 각각 설계 할 수 있습니다. 최대 값 대기열을 예로 들어 현재 대기열의 최대 값, 두 번째로 큰 값 등이 처음부터 끝까지 순서대로 저장되고 대기열의 첫 번째 요소가 최대 값입니다. 현재 창.

(2) 코드

class Solution {
    
    
    public int longestSubarray(int[] nums, int limit) {
    
    
        int n = nums.length, ans = 0;
        Deque<Integer> small = new LinkedList<>(), large = new LinkedList<>();//记录窗口中大、小值
        for (int l = 0, r = 0; r < n; r++) {
    
    //滑动窗口
            while (!small.isEmpty() && nums[r] < small.peekLast())//弹出比当前右端点大的小值
                small.pollLast();
            small.offerLast(nums[r]);
            while (!large.isEmpty() && nums[r] > large.peekLast())//弹出比当前右端点小的大值
                large.pollLast();
            large.offerLast(nums[r]);
            while (large.peekFirst() - small.peekFirst() > limit) {
    
    //超出限制,移动左端点
                if (small.peekFirst() == nums[l])
                    small.pollFirst();
                if (large.peekFirst() == nums[l])
                    large.pollFirst();
                l++;
            }
            ans = Math.max(ans, r - l + 1);//计算区间长度
        }
        return ans;
    }
}

(3) 결과

실행 시간 :
34ms, 모든 Java 제출에서 사용자의 90.51 %를 이겼습니다 . 메모리 소비 : 55.1MB, 모든 Java 제출에서 사용자의 65.18 %를 이겼습니다.

세, 기타

아무것도.

추천

출처blog.csdn.net/zml66666/article/details/114233506