투 포인터
등차 수열을 이용한 문제이다. 예를 들어 1,2,3,1,2
를 예로 들어 본다면,
1
, 1,2
, 1,2,3
이 되며2
, 2,3
, 2,3,1
이 된다.st
, ed
와 방문처리를 할 수 있는 배열과 함께, 나올 수 있는 모든 경우의 수를 탐색한다. 만약 중복되는 것이 나오는 경우는 st
값을 늘리고 이전 시작값의 방문처리를 다시 false
로 만드는 과정을 반복한다. 중복되는 값이 나왔을 때의 모든 경우의 수는 ed-st
이다.
만약 임의의 st
를 시작으로 ed
값이 N
의 범위를 초과하게 되는 경우는 더이상 중복되는 값이 존재하지 않는다는 뜻이다, 현재 st~ed
범위의 등차수열을 구하는 공식은 이다.
ed
값이 +1 초과되어 나오지만 ed
는 정확히 index 값이므로, 이론상 ed-st
를 했을 때 어차피 숫자 갯수가 하나 모자르니 문제 없었다.
erase()
를 써봤지만 사용하는 메모리나 시간을 똑같더라. 여튼 오늘의 배운점은 이면 400kb 이니 팍팍 쓰자!#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int N, st, ed;
vector<int> v;
void input() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N;
int num;
for (int i = 0; i < N; i++) {
cin >> num;
v.push_back(num);
}
}
void solve() {
unordered_map<int, int> m;
long long ans = 0;
while (ed < N) {
if (!m[v[ed]]) {
m[v[ed++]]++;
} else {
ans += ed - st;
m[v[st++]]--;
};
}
ans += (long long) (ed - st) * (ed - st + 1) / 2;
cout << ans;
}
int main() {
input();
solve();
}