nums라는 숫자 목록과 또 다른 숫자 k가 있다고 가정하면 목록에서 최대 한 번만 하위 목록을 제거할 수 있습니다. k보다 엄격하게 작은 숫자와 k보다 큰 숫자의 양이 같도록 가장 긴 결과 목록의 길이를 찾아야 합니다.
따라서 입력이 nums =[6, 10, 8, 9, 3, 5], k =6과 같으면 출력은 5가 됩니다. 마치 하위 목록 [9]를 제거하면 [6, 10, 8, 3, 5] 그리고 6보다 작은 두 개의 숫자[3, 5]와 6보다 큰 두 개의 숫자[10, 8]가 있습니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
- nums + 1과 같은 크기의 배열 v를 정의하고 0으로 채움
- cnt :=0
- 초기화 i의 경우:=0, i <숫자의 크기일 때 업데이트(i를 1만큼 증가), 수행 -
- nums[i]
- (cnt를 1씩 증가)
- nums[i]
- 그렇지 않으면 nums[i]> k일 때:
- (cnt를 1씩 감소)
- v[i + 1] =cnt
- delta :=v의 마지막 요소
- m[v[i] - v의 마지막 요소가 0과 같지 않거나 (v[i] - v의 마지막 요소가 0과 같은 경우) -
- ans :=as 및 i의 최소값 - m[v[i] - v의 마지막 요소
- m[v[i]] :=나
- 0을 반환
- 숫자의 반환 크기
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예시
#include <bits/stdc++.h> using namespace std; class Solution { public: int solve(vector<int>& nums, int k) { vector<int> v(nums.size() + 1, 0); int cnt = 0; for (int i = 0; i < nums.size(); ++i) { if (nums[i] < k) ++cnt; else if (nums[i] > k) --cnt; v[i + 1] = cnt; } if (v.back() == 0) return int(nums.size()); int delta = v.back(); map<int, int> m; int ans = INT_MAX; for (int i = 1; i <= v.size(); ++i) { if (m[v[i] - v.back()] != 0 || v[i] - v.back() == 0) { ans = min(ans, i - m[v[i] - v.back()]); } m[v[i]] = i; } if (ans == INT_MAX) return 0; else return int(nums.size() - ans); } }; main(){ Solution ob; vector<int> v = {6, 10, 8, 9, 3, 5}; int k = 6; cout << ob.solve(v, k); }
입력
{6, 10, 8, 9, 3, 5}, 6
출력
5