처음엔 입력을 받을 때 특정 값이 반복되며 그 값에 해당하는 인덱스를 각각 벡터에 저장해주어 나중에 범위를 구하면 된다고 생각하였다. 이 방법으로 구현하니까 포함이 되지 않는 경우가 존재하여 답이 안나왔다.(이렇게 푸는 방법이 있을 수도 있지만 나는 생각해내지 못했다.)
그렇게 고민하다 투포인터를 이용하여 풀 수 있다는 것을 알 수 있었다. 전체 경우를 구한다음 중복되는 경우를 빼주는 방식으로 구하였다. 중복되는 경우를 찾기 위해서 투포인터를 이용한다.
먼저 방문한 수에 대한 여부를 배열에 저장하고 이미 있는 수를 또 방문한다면 중복이니까 N - rightPointer를 해주었다.(현재 경우에 나올 수 있는 중복되는 경우의 수) 그 다음에 left pointer의 방문여부를 0으로 만들어 준다. 같은 방식으로 진행한 다음 전체 경우의 수 - 전체 중복 경우의 수를 해준다.
2-1. 1번 접근 방식과 다른 점은 배열의 처음부터 진행하며 빠지는 경우 없이 다 구할 수 있다는 점인 것 같다.
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <math.h>
#include <set>
#include <map>
#include <deque>
using namespace std;
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0, 0, 1, -1 };
long long N;
int isVisited[100001] = { 0 };
int nums[100001] = { 0 };
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
long long totalCnt = (N * (N + 1)) / 2;
for (int i = 0; i < N; i++)
{
cin >> nums[i];
}
long long totalExept = 0;
int lp = 0;
int rp = 1;
isVisited[nums[lp]] = 1;
while (rp < N)
{
if (isVisited[nums[rp]] == 1)
{
isVisited[nums[lp]] = 0;
totalExept += N - rp;
lp++;
}
else
{
isVisited[nums[rp]] = 1;
rp++;
}
}
cout << totalCnt - totalExept;
return 0;
}