dev_beomgeun
꾸준하게 차근차근
dev_beomgeun
전체 방문자
오늘
어제
  • 분류 전체보기 (170)
    • 전공 (0)
      • 운영체제 (0)
      • 알고리즘 (0)
      • 자료구조 (0)
      • 데이터베이스 (0)
      • 네트워크 (0)
    • 개발 공부 (32)
      • 웹 (6)
      • 리눅스 (4)
      • 머신러닝 (1)
      • 스프링 (17)
      • Git (2)
      • AWS (2)
    • 개발 도서, 강의 (3)
      • 스프링 입문을 위한 자바 객체지향의 원리와 이해 (0)
      • 모든 개발자를 위한 HTTP 웹 기본 지식(김영한.. (2)
      • 스프링 부트와 AWS로 혼자 구현하는 웹서비스 (1)
    • 문제 풀이 (118)
      • 백준 알고리즘 (72)
      • 프로그래머스 알고리즘, SQL (38)
      • Hackerrank SQL (8)
    • 프로젝트 기록 (4)
      • 캡스톤 종합설계 (4)
      • 반려하루 프로젝트 (0)
    • 활동 기록 (12)
      • 네이버 부스트캠프 (7)
      • 취준 & 코테 (4)
      • 소프트웨어 마에스트로 13기 (1)
    • 이것저것 (1)

블로그 메뉴

  • 홈
  • 깃허브
  • 링크드인
  • 방명록

공지사항

인기 글

태그

  • 스프링
  • 네이버 부스트캠프
  • 회고
  • 서블릿
  • AI Tech
  • 프로그래머스
  • 기록
  • HackerRank mysql
  • BFS
  • c++
  • dp
  • 프로그래머스 SQL
  • 백준 DP
  • 반성
  • 그래프탐색
  • 일기
  • 백준
  • Hackerrank
  • 부스트캠프
  • Baekjoon

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
dev_beomgeun

꾸준하게 차근차근

[baekjoon 10816] 숫자 카드2 -  Hashmap, 이분탐색 (C++)
문제 풀이/백준 알고리즘

[baekjoon 10816] 숫자 카드2 - Hashmap, 이분탐색 (C++)

2021. 1. 1. 17:59
728x90

www.acmicpc.net/problem/10816

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,

www.acmicpc.net

입력 수들을 받고, 찾고자 하는 수에 해당하는 수가 몇 개가 있는지 출력하는 문제다.

입력 개수는 50만 개, 찾는 수 또한 50만 개로 일반적인 배열에 넣고 선형 탐색을 하게 되면 O(N^2)로 시간제한 1초를 넘기게 된다.

보통 c++기준 N = 1억이면 1초라고 한다.

 

따라서 보통의 시간 복잡도가 O(1)인 HashMap을 이용하거나 O(logN)인 이분 탐색을 이용해야 한다.

(이분 탐색은 문제 풀고 나서 알았다.)

 

 - HashMap을 이용한 풀이

(통과한 코드인데 ios::sync_with_stdio(false)와 cin.tie(0)을 해주기 전에는 시간 초과가 나왔다.)

#include <iostream>
#include <unordered_map>

using namespace std;

unordered_map <int, int> m;
int N, M, card;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> card;
		m[card]++;
	}
	cin >> M;
	for (int i = 0; i < M; i++) {
		cin >> card;
		cout << m[card] << " ";
	}
}

 

이분 탐색을 이용한 풀이는 Algorithm STL의 upper_bound, lower_bound을 사용한 풀이가 있었다.

이분 탐색을 위해서 오름차순 정렬을 해주고, upper_bound와 lower_bound을 이용해서 결과를 출력했다.

 - upper_bound : 찾고자 하는 값의 다음 값이 최초로 나타나는 위치

 - lower_bound : 찾고자 하는 값 이상이 처음 나타나는 위치

 

즉, 1 2 4 4 6 7에서

lower_bound(~,~,4)의 결과 : 3 (4 이상의 값이 처음 나타나는 위치)

upper_bound(~,~,4)의 결과 : 5 (4를 초과하는 값이 처음 나타나는 위치)를 이용해서 

사이의 값을 빼주면 2가 나오고 이것은 결국 저장된 4의 개수가 된다.

#include <iostream>
#include <algorithm>

using namespace std;

int arr[500002];
int N, M, card;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> card;
		arr[i] = card;
	}
	sort(arr, arr + N); // 이분탐색을 위해 오름차순 정렬

	cin >> M;
	for (int i = 0; i < M; i++) {
		cin >> card;
		cout << upper_bound(arr, arr + N, card) - lower_bound(arr, arr + N, card)<<" ";
	}
}

 

 

위가 이분탐색, 아래가 HashMap을 이용한 메모리, 시간이다.

 

그럼 왜 시간 복잡도가 더 작은 HashMap이 더 오래 걸렸을까?

 

질문하기에서 어떤 분께서 잘 설명을 해주셔서 가져와보았다.

-------------------------------------------------------------------

현실 세계에서는 N이 무한히 큰 경우가 거의 없기 때문에 O(lgN)과 O(1) 정도의 차이는 N의 크기에 따라 시간 복잡도에 붙은 상수로 자주 뒤집어집니다.

가령, 최소한의 비교로 원하는 수를 찾아야 하는 가상의 문제가 있다고 합시다.

N에 관계없이 항상 50번의 비교로 수를 찾는 어떤 O(1) 알고리즘과 N에 대해 ceil(lgN) 번의 비교를 하는 O(lgN) 알고리즘이 있으면,

복잡도만 봤을 때는 O(1)이 나음에도 불구하고, N이 조 단위를 넘어가지 않는 이상 O(lgN)이 O(1) 보다도 빠릅니다.

이런 상황은 심지어 O(N)과 O(N^2)같이 시간 복잡도가 크게 차이나는 경우에도 자주 일어납니다.

출처 : www.acmicpc.net/board/view/57406

-------------------------------------------------------------------

 

그렇다고 한다. O(logN)이 O(1) 보다 더 빠를 수 있다는 사실을 알게 되었다.

728x90
저작자표시 비영리 변경금지 (새창열림)

'문제 풀이 > 백준 알고리즘' 카테고리의 다른 글

[baekjoon 11726] 2xN 타일링- DP(동적 프로그래밍) (C++)  (0) 2021.01.03
[baekjoon 7662] 이중 우선순위 큐 - Map, MutliMap (C++)  (0) 2021.01.02
[baekjoon 11650] 좌표 정렬하기- 정렬 (C++)  (0) 2021.01.01
[baekjoon 1978] 소수 찾기- 소수, 에라토스테네스의 체 (C++)  (0) 2020.12.30
[baekjoon 17269] 이름궁합 테스트- 문자열, 구현 (C++)  (0) 2020.12.27
    '문제 풀이/백준 알고리즘' 카테고리의 다른 글
    • [baekjoon 11726] 2xN 타일링- DP(동적 프로그래밍) (C++)
    • [baekjoon 7662] 이중 우선순위 큐 - Map, MutliMap (C++)
    • [baekjoon 11650] 좌표 정렬하기- 정렬 (C++)
    • [baekjoon 1978] 소수 찾기- 소수, 에라토스테네스의 체 (C++)
    dev_beomgeun
    dev_beomgeun
    백엔드 개발을 하며 얻은 지식과 경험을 공유합니다. 현재 카카오페이에서 백엔드 엔지니어로 일하고 있습니다.

    티스토리툴바