Data Structure / Algorithm (2)
Data Structure
List
LinkedList
ArrayList
A-1) ArrayList (랜덤 접근, 끝 삽입 강함)
ArrayList (랜덤 접근, 끝 삽입 강함)import java.util.*;
// 선언/초기화
List<Integer> al = new ArrayList<>(); // 기본
List<Integer> alCap = new ArrayList<>(1<<20); // 초기 용량
al.add(10); al.add(20);
al.add(1, 15); // 중간 삽입 O(N)
al.set(0, 7);
int v = al.get(1); // O(1)
al.remove(al.size()-1); // 끝 삭제 O(1) 평균
al.remove(Integer.valueOf(15)); // 값으로 삭제(첫 매치)
// 반복/검색
for (int x : al) { /* read only */ }
int idx = al.indexOf(20); // O(N), 없으면 -1
boolean has = al.contains(7); // O(N)
// 정렬/역정렬
al.sort(Comparator.naturalOrder()); // 오름차순
al.sort(Comparator.reverseOrder()); // 내림차순
// 배열 <-> 리스트
Integer[] boxed = al.toArray(new Integer[0]);
int[] prim = al.stream().mapToInt(Integer::intValue).toArray();
List<Integer> fromArr = new ArrayList<>(Arrays.asList(1,2,3));
// 부분리스트(뷰!)
List<Integer> sub = al.subList(0, Math.min(3, al.size())); // 원본과 연결된 뷰언제? 인덱스 접근 많고, 주로 뒤에 추가할 때.
주의: 중간 삽입/삭제 많으면 느림(shift 비용).
A-2) LinkedList (노드 연결, 연결지점 알면 삽입/삭제 O(1))
LinkedList (노드 연결, 연결지점 알면 삽입/삭제 O(1))언제? 리스트 중간에 iterator로 빈번 삽입/삭제.
주의: 인덱스 기반 접근/삽입/삭제는 O(N) → 웬만하면
ArrayList.
Map
HashMap
B-1) HashMap<K,V> (평균 O(1))
HashMap<K,V> (평균 O(1))언제? 빈도/카운팅, 인덱스 매핑.
주의: 커스텀 키는
equals/hashCode구현 필요. 큰 입력은 초기 용량 여유.
Set
HashSet
C-1) HashSet<E> (중복 제거/멤버십 테스트)
HashSet<E> (중복 제거/멤버십 테스트)정렬/이웃 탐색 필요 →
TreeSet(ceiling,floor,higher,lower유용).
Heap(Priority Queue)
Max Heap
Min Heap
D-1) Min Heap / Max Heap / 커스텀 비교
D-2) Top-K & K-유지 패턴
D-3) kth 요소 / running median
Stack / Queue / Dequeue
ArrayDeque로 통일:Stack/LinkedList보다 빠르고 안전.
E-1) Stack (후입선출)
E-2) Queue (선입선출)
E-3) Deque (양끝 삽입/삭제)
E-4) 모노토닉 큐 (슬라이딩 윈도우 최대 O(N))
Matrix / Grid
F-1) 선언/초기화/입력
F-2) 경계/이동/방문
F-3) BFS (최단거리)
F-4) 0-1 BFS (비용 0/1)
F-5) Flood Fill (영역 개수/면적)
F-6) 2D Prefix Sum (누적합)
F-7) 행/열 조작(회전/전치)
공통 유틸
Graph
구현(인접리스트/인접행렬)
탐색(BFS/DFS)
최단 경로(Shortest Path) (BFS, Dijstra)
최소 신장 트리(MST) (Kruskal) : 최소 비용 연결
사이클 판별
위상 정렬(Topology Sort)
Tree
| 트리는 사이클 없는 연결 그래프. 보통 인접리스트로 다룸. 1을 루트로 잡는 예시.
구현(트리 노드 정의/인접리스트로)
탐색(BFS/DFS)
트리 높이 구하기
깊이 / 부모 찾기
서브 트리 크기 계산하기
Tree DP
Trie
Segment Tree
BST
최소 공통 조상(LCA)
트리 지름(가장 먼 두 점 거리)
Tip
G-1) 빈도 상위 K개 (문자/정수 공통)
G-2) 두 수 합(존재 여부)
G-3) 그래프 인접리스트 & 다익스트라
G-4) LinkedHashMap으로 LRU 캐시 (간단형)
ArrayList vs LinkedList: 중간 삽입/삭제가 “많고 위치를 iterator로 알고 있으면” LinkedList, 아니면 거의 ArrayList.
PriorityQueue 비교자:
a[1]-b[1]금지 →Integer.compare(오버플로 방지).Map 값-리스트:
computeIfAbsent패턴 기억.Set 순회 중 삭제: for-each 금지 →
Iterator.remove()또는 역순 인덱스.Deque: 스택/큐 모두
ArrayDeque사용.Grid: 방문/경계/방향 배열 템플릿 고정해두기.
초기 용량: 대량 데이터 시 rehash 줄이기 (
new HashMap<>(1<<20)등).출력: 누적 후 한 번에
StringBuilder로.그래프 최단: 무가중치→BFS, 0/1→0-1 BFS, 양수 가중치→Dijkstra.
MST: 간선 정렬 + DSU (Kruskal).
사이클: 무방향(DFS+parent), 방향(DFS 색칠).
위상정렬: Kahn(진입차수 0 큐).
트리 기본:
dfsTree/bfsTree로parent, depth, subSize한 번에.LCA: Binary Lifting 전처리 후 O(logN).
Trie/SegTree/BST: 상황 맞게 가져다 쓰기.
Algorithm
Sorting (배열/리스트/객체)
1. 기본 배열 정렬
2. 2차원 배열 정렬
3. 객체 정렬 (Comparable & Comparator)
Comparator 사용 예:
4. Map 정렬 (Key, Value 기준)
5. 우선순위 큐(PriorityQueue)와 정렬
누적합(Prefix Sum)/구간합(Interval Sum)/ Sliding Window / Two Pointer
1. Prefix Sum (1D/2D)
2D:
2. Sliding Window
3. Two Pointer
BFS/DFS
BackTracking
재귀, 가지치기, visited
1. 기본
2. 순열 (중복X)
중복허용 순열 → if(!used[i]) 제거.
3. 조합 (중복X)
중복허용 조합 → comb(i, depth+1).
Brute Force
모든 경우의 수 탐색.
예: 20개 이하 원소 →
2^N부분집합 완전탐색 가능.
Recursive
Ractorial
Fibonacci
Binary Search
Greedy
지역 최적 선택 → 전체 최적 도달 (증명 필요).
예: 회의실 배정, 동전 거스름(단위 제한), 최소 스패닝 트리, 허프만 코딩.
DP (Dynamic Programming)
1. Bottom-Up (Tabulation, for문)
2. Top-Down (Memoization, Recursive)
구현/시뮬레이션(Implemetatio/Simulation)
방향벡터 & 이동시도 & 범위 체크 & 방향 이동
회전 (1차원, 2차원 90도, 부분 회전)
1) 1차원 배열 회전 (k칸, 오른쪽 양수)
2) 2차원 90도 회전
3) 부분 회전 (서브행렬 테두리 한 칸 회전: 시계)
큐 & 시간 흐름 시뮬레이션
상태 갱신
중력 적용
배열 한 칸씩 돌리기
벽 부딪힘 이동 처리
속도에 따라 이동/방향 바꾸기 (장애물/미끄럼)
조건에 따라 상태 변화 반복 / 조건을 만족할 때까지 무한 반복
나선형 배열 채우기 (시계 방향)
“조건 만족할 때까지 무한 루프” 틀
Map 상태 디버깅 함수
배열 복사 (옅은 복사, 깊은 복사)
🧩 미니 종합 예시: “중력+회전+시간 시뮬”
주사위
A. 주사위 상태 & 굴리기 연산
B. 격자와의 상호작용(대표 규칙)
이동한 칸 값이 0이면 → 바닥면(bottom) 값을 칸에 복사
0이 아니면 → 칸의 값을 바닥면으로 복사하고 칸을 0으로
출력은 보통 윗면(top)
Last updated