문제 링크

요약

  • 탐색을 돕는 자료구조를 잘 선택하기

최종

  • 같은 값을 가지는 index 들을 전부 vector 에 넣은 다음, query 의 index 를 이용해 해당 index 에 대한 vector 내에서의 위치를 binary search 로 찾아 양옆으로의 distance 를 구하는 방식으로 구현함.
#define MIN(a, b) ((a) < (b) ? (a) : (b))
 
class Solution {
	int bsearch(vector<int> &field, int target) {
		int l = 0;
		int r = field.size() - 1;
 
		while (l + 1 < r) {
			int m = (l + r) >> 1;
 
			if (field[m] < target) {
				l = m;
			} else {
				r = m;
			}
		}
 
		if (field[l] == target) {
			return l;
		}
 
		return r;
	}
public:
	vector<int> solveQueries(vector<int>& nums, vector<int>& queries) {
		map<int, vector<int>> num_to_idx;
		vector<int> ret;
 
		for (int i = 0; i < nums.size(); i++) {
			num_to_idx[nums[i]].push_back(i);
		}
 
		for (int q : queries) {
			auto &idxs = num_to_idx[nums[q]];
			int size = idxs.size();
 
			if (size == 1) {
				ret.push_back(-1);
				continue;
			}
 
			int idx = bsearch(idxs, q);
 
			if (idx == 0) {
				ret.push_back(MIN(idxs[1] - idxs[0], nums.size() + idxs[0] - idxs[size - 1]));
			} else if (idx == size - 1) {
				ret.push_back(MIN(idxs[idx] - idxs[idx - 1], nums.size() - idxs[idx] + idxs[0]));
			} else {
				ret.push_back(MIN(idxs[idx + 1] - idxs[idx], idxs[idx] - idxs[idx - 1]));
			}
		}
 
		return ret;
	}
};
  • 성능은 구린데 다른 solution 봐도 크게 다르지 않는듯

삽질 기록

  • 의 성능이 구려서 추가적으로 시도해본 것들

List 사용

  • 특정 index 에 대해, 같은 값을 가지는 이전/이후의 index 를 list 로 연결해서 빠르게 이전/이후 index 를 찾아 distance 를 구하는 방식
  • 이것도 느리다.

Set 사용

  • 코드에서 binary search 대신 setRB Tree 를 사용한 방식
  • 그래도 느리다.

거리 증가

  • Distance 를 1씩 증가시켜가면서 처음으로 만나는 값이 같은 놈을 찾는 방식.
  • Timeout 난다.

같은 숫자 index 순회

  • 코드에서 binary search 안하고 그냥 처음부터 순회하는 방식.
  • Timeout 난다.