본문 바로가기

전체 글139

[DataStructure/Tree] 우선순위 큐, 힙, 이진 탐색 트리의 개념과 차이점 정리 트리 자료구조를 공부하다 보니 이진 트리(Binary Tree), 힙(Heap), 이진 탐색 트리(BST), 우선순위 큐(Priority Queue) 등의 개념이 서로 얽혀 있어 혼란스러웠습니다.각 개념의 관계를 정리하면 트리를 더 잘 이해하는 데 도움이 될 것 같아, 이번 기회에 깔끔하게 정리해 보았습니다.1. 이진 트리 (Binary Tree)개념각 노드는 최대 두 개의 자식 노드를 가질 수 있는 트리 구조입니다.이진 트리는 단순한 자료구조이며, 정렬 방식이나 데이터 접근 규칙이 따로 정해져 있지 않습니다.노드 개수는 최대 2^h - 1 개입니다. (h는 트리의 높이)특징탐색 규칙이 없는 단순한 구조적 개념입니다.왼쪽, 오른쪽 자식을 가지는 트리 형태일 뿐입니다.예시 A / \.. 2025. 2. 12.
[DataStructure/Map, Set, List] Map vs Set vs List: 순서 보장과 중복 허용 차이 정리 Map, Set, List는 대부분의 프로그래밍 언어에서 자주 사용되는 대표적인 자료구조입니다.어렴풋이 알고 있다고 생각했지만, 막상 설명해보려니 정확하게 이해하지 못하고 있다는 느낌이 들었습니다.그래서 이번 글에서는 Map, Set, List의 동작 방식과 구현체별 차이점을 정리하면서, 순서 보장 여부와 중복 허용 여부를 명확하게 정리해두려고 합니다.1. Map, Set, List의 기본적인 차이점특징Map (Key-Value 저장)Set (중복 없는 값 저장)List (중복 허용, 순서 유지)데이터 저장 방식Key-Value 쌍으로 저장중복 없는 단일 값(Value) 저장중복을 허용하며 순서대로 값 저장중복 허용 여부Key 중복 ❌, Value는 중복 가능중복 ❌중복 ⭕순서 보장 여부구현체에 따라 다.. 2025. 2. 12.
[DataStructure/Set] Set의 contains() 시간 복잡도 정리: HashSet, TreeSet, LinkedHashSet 비교 Set을 공부하던 중, Set.contains() 메서드의 시간 복잡도가 궁금했는데, Set의 자료구조 종류에 따라 contains()의 성능이 달라진다는 것을 알게 되었습니다.특히, HashSet, TreeSet, LinkedHashSet과 같이 구현 방식이 다른 Set은 각각 다른 자료구조를 사용하기 때문에 contains()의 시간 복잡도도 다르게 동작합니다.이번 글에서는 Set의 종류별 contains() 성능 차이와 시간 복잡도를 정리해 보겠습니다.1. Set.contains()의 시간 복잡도는 언제 달라질까?Set.contains(element) 메서드는 Set에 특정 요소가 존재하는지 여부를 확인하는 메서드입니다.하지만 Set의 내부 자료구조에 따라 검색 속도가 다르게 동작합니다.HashSe.. 2025. 2. 11.
[DataStructure/LinkedHashMap] LRU 캐시와 LinkedHashMap 기반 Glide Bitmap 최적화 최근에 LinkedList 사용 예제를 공부하던 중, LRU 캐시(Least Recently Used Cache)라는 개념을 알게 되었습니다.LRU 캐시는 오래 사용되지 않은 데이터를 자동으로 삭제하는 캐싱 기법으로, 메모리 관리에서 중요한 역할을 합니다.그런데, LRU 캐시는 단순한 LinkedList가 아니라, "해시 테이블과 이중 연결 리스트가 결합된 LinkedHashMap을 활용하여 구현되는 경우가 많다"는 것을 알게 되었습니다.또한, 안드로이드에서 Glide 라이브러리도 LinkedHashMap을 기반으로 한 LRU 캐시를 활용하여 Bitmap(이미지) 데이터를 캐싱하고 있었습니다.따라서 이번 글에서는 LRU 캐시의 개념과 함께, Glide가 이를 활용하여 어떻게 성능을 최적화하는지 정리해 두.. 2025. 2. 11.
[Algorithm/Kotlin] 백준 1003번 피보나치 함수: DP를 활용한 풀이법 문제 설명주어진 문제는 재귀적으로 정의된 피보나치 함수에서 0과 1이 출력되는 횟수를 구하는 것입니다.C++의 재귀 구현을 보면, fibonacci(n)을 호출할 때 fibonacci(n-1)과 fibonacci(n-2)를 호출하는 방식으로 동작합니다. 이 과정에서 동일한 fibonacci 함수가 여러 번 호출되며 중복 계산이 발생합니다.예를 들어, fibonacci(3)을 호출하면 아래와 같은 과정이 발생합니다:fibonacci(3) -> fibonacci(2) + fibonacci(1)을 호출합니다.fibonacci(2) -> fibonacci(1) + fibonacci(0)을 호출합니다.fibonacci(1)이 1을 출력하고 반환합니다.fibonacci(0)이 0을 출력하고 반환합니다.fibonac.. 2025. 2. 7.
[Android/Compose] Recomposition: 상태 변화에 따른 UI 갱신 Jetpack Compose를 사용하면서 기존 방식과 다르게 LiveData.observe() 같은 코드도 없고, notifyDataSetChanged()를 호출하지 않았는데도 UI가 알아서 갱신되는 것이 신기하게 느껴졌습니다."LiveData도 사용하지 않았는데, 왜 상태가 변하면 UI가 자동으로 업데이트되지?"라는 궁금증이 들었습니다.기존 XML 기반의 View 시스템에서는 명시적인 호출이 필요했지만, Compose에서는 mutableStateOf만으로 UI가 알아서 갱신됩니다. 이는 Recomposition(재구성) 덕분입니다.이번 글에서는 공부한 내용을 바탕으로 Compose의 Recomposition이 무엇인지, 그리고 어떻게 동작하는지를 정리 해 보겠습니다.Recomposition이란?Reco.. 2025. 2. 6.
[Android/Kotlin] mutableMapOf vs hashMapOf 차이점 및 성능 비교 Kotlin에서 Map을 사용할 때 mutableMapOf와 hashMapOf 중 어떤 것을 선택하는 것이 더 좋을까요? 이번 글에서는 두 가지의 차이점과 성능 비교를 통해 언제 어떤 것을 선택하면 좋은지를 알아보겠습니다.1. mutableMapOf vs hashMapOf 차이점mutableMapOfval sitesAndPasswords = mutableMapOf()내부적으로 LinkedHashMap을 사용합니다.입력 순서를 유지하는 특징이 있습니다.성능은 일반적인 HashMap과 동일 (O(1) 조회, 삽입 가능).hashMapOfval sitesAndPasswords = hashMapOf()명시적으로 HashMap을 사용합니다.입력 순서를 유지하지 않음 (순서가 중요하지 않다면 더 적합).성능은 mu.. 2025. 2. 6.
[Android/Compose] Modifier를 파라미터로 전달하는 이유 Jetpack Compose에서 Column과 같은 레이아웃 컴포저블을 사용할 때, Modifier를 기본 인자로 직접 설정할 수 있습니다.그런데, 코드에서 Modifier를 바로 적용할 수 있는데도 불구하고, 굳이 파라미터로 Modifier를 전달하는 방식을 사용하는 이유가 궁금했습니다.이러한 의문을 가지고 공부하던 중, Compose의 재구성(Recomposition)과 성능 최적화와 관련된 중요한 개념을 알게 되었습니다.이 글에서는 왜 Modifier를 직접 선언하는 것이 아니라, 파라미터로 전달하는 것이 더 좋은 방법인지 정리해 보겠습니다.Modifier를 직접 사용하면 생기는 문제처음에는 아래처럼 Column 내부에서 바로 Modifier.padding(16.dp)을 적용하는 것이 자연스러워 보.. 2025. 2. 5.
[Android/Kotlin] fold 사용법과 예제 Kotlin의 fold는 컬렉션을 순회하면서 초기값을 설정하고, 이전 연산의 결과를 누적하면서 값을 계산하는 데 사용됩니다. 특히, 누적된 값을 유지하면서 새로운 값을 추가해야 하는 경우 유용합니다.이번 글에서는 fold를 활용하여 ATM 대기 시간 최소화 문제를 해결하는 예제를 통해 fold의 동작 원리를 알아보겠습니다.fold의 기본 구조initial: 초기값 (연산을 시작할 때 사용할 값)operation: 리스트의 각 요소를 순회하며 누적값(acc)과 현재 요소(T)를 사용해 연산을 수행하는 람다 함수결과값(R)이 누적되면서 최종 결과를 반환기본 예제: 리스트의 합 구하기val numbers = listOf(1, 2, 3, 4, 5)val sum = numbers.fold(0) { acc, num.. 2025. 2. 5.
[Android/Compose] Spacer를 활용한 UI 요소 중앙 및 하단 배치 Compose를 이용해 화면을 구성하며, UI의 한 요소는 화면 중앙에 배치하고 다른 요소는 하단에 고정해야 하는 상황이 있었습니다.이 요구사항을 어떻게 해결할 지 고민하던 중, Spacer(modifier = Modifier.weight(1f))를 활용하여 원하는 대로 배치할 수 있었습니다.이 글에서는 해당 방법을 이용해 원하는 레이아웃을 구현한 과정을 정리해 보겠습니다.Spacer를 활용한 중앙 및 하단 배치구현 코드@Composablefun BusinessCardApp() { Column( modifier = Modifier.fillMaxSize(), // 전체 화면을 차지하도록 설정 horizontalAlignment = Alignment.CenterHorizonta.. 2025. 2. 4.
[Android/Kotlin] 코틀린의 mutableMapOf()는 왜 LinkedHashMap을 사용할까? 코틀린에서 mutableMapOf()를 사용하면 내부적으로 LinkedHashMap이 생성됩니다.처음에는 mutableMapOf()를 단순히 사용했지만, 왜 기본 구현체가 LinkedHashMap일까? 라는 의문이 들었습니다.이 글에서는 그 이유를 고민해보고, HashMap, LinkedHashMap, TreeMap의 차이를 비교한 내용을 정리해보겠습니다.1. mutableMapOf()는 LinkedHashMap을 사용한다우선, mutableMapOf()가 내부적으로 어떤 자료구조를 사용하는지 확인해보겠습니다. 즉, 코틀린의 mutableMapOf()는 기본적으로 LinkedHashMap을 사용한다는 것을 확인할 수 있었습니다.그렇다면 왜 LinkedHashMap을 기본으로 사용할까?2. LinkedHa.. 2025. 2. 4.
[Algorithm/Kotlin] 백준 11723번 집합: 집합 연산 최적화 MutableSet vs. 비트마스크(Bitmask) 이번 글에서는 MutableSet과 비트마스크(Bitmask) 두 가지 방식을 비교하며, 새롭게 알게 된 비트마스크를 활용한 집합 연산 최적화 방법을 정리해보겠습니다.1. 문제 설명비어있는 공집합 S가 주어졌을 때, 다음 연산을 수행하는 프로그램을 작성하세요.add x : S에 x를 추가 (1 ≤ x ≤ 20)remove x : S에서 x를 제거check x : S에 x가 있으면 1, 없으면 0 출력toggle x : S에 x가 있으면 제거, 없으면 추가all : S를 {1, 2, ..., 20}으로 변경empty : S를 공집합 {}으로 변경입력M (1 ≤ M ≤ 3,000,000): 연산 개수이후 M개의 연산이 주어짐출력check 연산이 수행될 때마다 결과를 출력2. 문제 해결 아이디어이 문제를 해결.. 2025. 2. 3.
반응형