묻고 답해요
143만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[파이썬/Python] 문과생도 이해하는 DFS 알고리즘! - 입문편
graph
dfs 영상을 쭉 보고있는데요 ㅎ문제들 마다 규칙이거의 무조건적으로 visited 와 2차원 graph 가 생성이 되나요 ??visited = []graph = [[False] *MAX for _ in range(MAX)]2. MAX 를 두시는 이유가 뭔가요 ??
-
해결됨[파이썬/Python] 문과생도 이해하는 DFS 알고리즘! - 입문편
재귀 함수 Depth
영상에서 23:48 부분 보고있는데요.칼럼 2에 5를 제일 하단에다가 적었는 이유가 어떤 규칙이 있는건가요 ??그리고 5 옆에는 비워두고 1 ( 무시 ) , 2 ( 무시 ) 6을 적으신것도 어떤 규칙이 있는건가 ? 궁금해서 여쭤봅니다 !
-
해결됨[파이썬/Python] 문과생도 이해하는 DFS 알고리즘! - 입문편
백준 DFS
백준을 기준으로 하시는 이유가 있나요 ??
-
해결됨2주만에 통과하는 알고리즘 코딩테스트 (2024년)
백트래킹 관련해서 질문 드립니다!
n = int(input()) # 식재료 개수 minimums = list(map(int, input().split())) # 최소 영양소 기준 ingredients = [list(map(int, input().split())) for _ in range(n)] # 재료들 # 선택한 식재료를 담을 배열 초기화 picked = [] result_picked = [] # 최소 비용 초기화 (정답값) min_cost = 987_654_321 # 조건 확인 def is_bigger(sum_nutrients): global minimums for i in range(4): if sum_nutrients[i] < minimums[i]: return False return True # subset 구하기 def recursion(k): global picked, min_cost, result_picked if k == n: # 재료를 모두 선택했다면 # 뽑은 재료가 조건에 만족하는지 확인 # picked의 영양소들의 합이 minimums의 각 최소 영양소보다 커야 함 # 뽑은 재료의 각 영양소의 합을 담기 sum_nutrients = [0, 0, 0, 0] sum_cost = 0 for i in range(len(picked)): sum_cost += ingredients[picked[i]][4] # 비용 담기 for j in range(4): sum_nutrients[j] += ingredients[picked[i]][j] # 최소 영양소보다 큰 지 확인 # 근데 사전 순으로 가장 빠른 것을 출력해야 한다. # 어떻게 ? if is_bigger(sum_nutrients) and sum_cost <= min_cost: if sum_cost < min_cost: min_cost = sum_cost # 최소 비용 업데이트 result_picked = picked[:] # 선택한 배열 저장 elif sum_cost == min_cost and picked < result_picked: result_picked = picked[:] return # 뽑은 재료의 인덱스를 picked에 담고 picked.append(k) recursion(k + 1) # 다음 재료 선택 # 재료 선택 안하는 경우엔 picked.pop() # 현재 재료를 빼고 recursion(k + 1) # 다음 재료 선택 recursion(0) # 출력 if min_cost == 987_654_321: print(-1) else: print(min_cost) res = [x + 1 for x in result_picked] print(*res) 19942 다이어트 문제입니다.저는 항상 백트래킹 할 때 이렇게 매개변수를 그냥 간단히 하는 식으로 하는데, 강사님은 매개변수에다가 설정을 하시더라구요강의보면서 직관적이기도 하고 되게 좋은 방법이라고 생각했는데,이렇게 해도 상관없나요?
-
미해결김영한의 실전 자바 - 중급 2편
comparable 질문
안녕하세요.강의에서 다음의 코드를 비교한 걸 보여주셨을 때 콘솔에 출력되는 개수가 다른데 왜 그런걸까요 ? 자바 버전에 따라 내부 구현된 정렬 알고리즘이 달라서 그럴까요 ? (강의는 출력 2개)@Override public int compareTo(MyUser o) { System.out.println(this + "vs " + o); return this.age < o.age ? -1 : (this.age == o.age ? 0 : 1); }MyUser{id='B', age=10}vs MyUser{id='A', age=30}MyUser{id='C', age=20}vs MyUser{id='B', age=10}MyUser{id='C', age=20}vs MyUser{id='A', age=30}MyUser{id='C', age=20}vs MyUser{id='B', age=10}
-
미해결김영한의 실전 자바 - 중급 2편
shuttle.showinfo를 호출시 실행창 질문
package generic.test.ex3 object UnitPrinter { //제네릭 메서드 fun <T : BioUnit>printerV1(t: Shuttle<T>){ println(t.showInfo()) } fun printerV2(shuttle: Shuttle<out BioUnit>){ println(shuttle.showInfo()) } fun <T : BioUnit>printerV3(t: Shuttle<T>){ val unit = t.out() println("이름: ${unit.name} hp:${unit.hp}") } fun printerV4(shuttle: Shuttle<out BioUnit>){ val unit = shuttle.out() println("이름: ${unit.name} hp:${unit.hp}") } }자바와 코틀린은 100퍼센트 호환이 된다고 해서 코틀린으로 강의를 보고있습니다.강의에선 v1과 v2로 인자로 받은 셔틀에서 unit을 꺼내어 내용을 출력했는데요. 그렇게 안하고 셔틀에서 바로showinfo를 호출해서 실행창에name : 마린 hp : 40kotlin.Unitname : 마린 hp : 40kotlin.Unit이렇게 줄바꿈으로 kotlin.Unit이라는게 자동적으로 붙는데 왜이런건가요 . 강의에서처럼 unit을꺼내어서 출력하면 안붙습니다.
-
해결됨이공계열 전공자를 위한 컴퓨팅사고와 인공지능
공지
강좌 운영이나 강의 내용에 관해 궁금한 점이 있으면 자유롭게 나누어주세요.교수자, 수강생 누구나 글쓰기와 댓글 쓰기가 가능합니다.
-
미해결데이터 사이언스 입문자를 위한 파이썬 및 통계
공지
강좌 운영이나 강의 내용에 관해 궁금한 점이 있으면 자유롭게 나누어주세요.교수자, 수강생 누구나 글쓰기와 댓글 쓰기가 가능합니다.
-
해결됨머신러닝, 딥러닝 입문 : 알고리즘 이해하기
공지
강좌 운영이나 강의 내용에 관해 궁금한 점이 있으면 자유롭게 나누어주세요.교수자, 수강생 누구나 글쓰기와 댓글 쓰기가 가능합니다.
-
해결됨[자바/Java] 문과생도 이해하는 DFS 알고리즘! - 입문편
graph를 2차원 배열 또는 List로 하는 기준을 어떤식으로 잡으면 좋을까요...?
아직 2차원 배열 또는 List로 해야되는것을 선택하는 기준이 잘 안잡히는데 문제에서 원하는 출력 형태가 연결된 모든 것들을 출력하는 느낌으로 질문한다면 List 이고, 그외에는 2차원 배열로 하면 될까요...? ㅠㅠ
-
해결됨데이터 마이닝
공지
강좌 운영이나 강의 내용에 관해 궁금한 점이 있으면 자유롭게 나누어주세요.교수자, 수강생 누구나 글쓰기가 가능합니다.
-
미해결김영한의 실전 자바 - 중급 2편
해시 알고리즘6 - 해시 충돌 구현 메모리 구조 관련 질문드립니다!
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 영한님 항상 정성이 담긴 강의해주셔서 대단히 감사합니다:)다름이 아니라 해당 부분 강의를 들었을 때 LinkedList와 배열의 조합으로 메모리 구조가 잘 떠오르지 않아서 제가 생각한 부분이 맞는지 질문드리는 점 양해 부탁드립니다(_ _)LinkedList 인덱스 배열[9] 부분에 9와 99가 같이 들어가는데요, 영한님께서 설명해주셨던 LinkedList 강의 부분 메모리 구조 그림으로 예를 든다면 배열[9] 부분에 노드가 이런식으로 두 개가 생성되는 것이 제가 이해한 부분이 맞을지 질문드립니다!항상 감사합니다 :))
-
해결됨비전공자의 전공자 따라잡기 - 자료구조(with JavaScript)
우선순위 큐 질문이 있습니다!
우선순위 큐 강의를 재미있게 보았는데, 큐와 우선순위큐가 먼저 실행 되는것을 실행하는 차이말고는 똑같은것 같은데 구현 코드는 힙 자료구조를 사용 하시더라고요! 그렇다면 힙과 우선순위 큐가 비슷하고 우선 순위 큐가 큐랑 비슷하니까 힙과 큐도 비슷한건가요?
-
미해결김영한의 실전 자바 - 중급 2편
Queue질문
안녕하세요.Queue 질문이 있어서 글 씁니다.add()와 offer()remove()와 poll() 은 각각 동작도 같고 반환 타입도 같던데 검색해보면 예외를 발생시키느냐 마냐의 차이라고 나와서요. 실제로 offer() 까보면 return add()라고 되어 있기도 하고 ...무슨 차이인지 그리고 어떨 때 어떤 걸 쓰는 게 좋을지 보충 설명 부탁드립니다.
-
해결됨코딩테스트 [ ALL IN ONE ]
min cost climbing stairs 완전탐색/dp 후반부에서 질문있습니다~
19:00쯤에서 보면 memo 정의 하실때 memo = [-1]*n으로 초기화하시고 시작하시는데n+1을 곱해줘야하지 top을 포함한 개숫가 초기화 되는게 아닌가 싶어서 질문드립니다혹시 제가 놓친게 있다면 말씀부탁드려요 ㅠㅠ
-
미해결김영한의 실전 자바 - 중급 2편
UML 클래스다이어그램 화살표 의미
컬렉션 프레임워크 - Set 강의 중 UML 클래스 다이어그램에 관해 궁금증이 생겼습니다. HashSet, TreeSet, LinkedHashSet 즉 Set의 주요 구현체들을 설명하셨을때,여기서 점선으로 된것과 실선으로 된것의 차이점은 무엇일까요??인터페이스인 Set의구현체로 HashSet , TreeSet 등이 있다는 것은 이해가 가지만, LinkedHashSet은 왜 실선으로 표시하는 걸까요?? 이 두개의 차이점에 대해 정확히 알고싶습니다!
-
미해결김영한의 실전 자바 - 중급 2편
HashMap 질문
안녕하세요.Set<Map.Entry<String, Integer>> 이게 좀 궁금해서 살펴보니 Set<E> 제네릭으로 받게끔 되어 있고 그럼 여기서 Map.Entry<String, Integer> 이게 하나의 타입처럼 사용이 된다는 건데 Map 클래스에서 Entry는 interface로 되어 있어서요.Map.Entry라고 썼다는거는 Entry도 인터페이스(클래스)니까 중첩 static class 처럼 쓰였다는건데 static도 안 붙어 있고 관련된 구현체도 Map 클래스 내부에는 없는 거 같아서요.추가 설명 부탁드립니다.
-
미해결김영한의 실전 자바 - 중급 2편
List.of 질문
안녕하세요.Arrays.asList()는 ArrayList를 반환하는 걸 확인했는데List.of()는 결과적으로 new ListN<>(tmp, false); 다음과 같은 ListN 객체를 반환하던데 이게 어떤 것인지 궁금합니다.List 구현체로 알고 있으면 될까요 ?
-
미해결김영한의 실전 자바 - 중급 2편
Set문의
안녕하세요.Set관련 2가지 질문드립니다.1. 문제풀이에서 보면 Set의 내용을 출력할 때 for-each문으로 Set의 내용을 출력하였는데, 기본적인 인덱스 접근은 아닐텐데 어떻게 for-each문으로 값을 찾아서 출력이 가능한 걸까요 ?(강의에 나온대로 hashIndex를 활용한 접근이라면 어느 index에 매핑될 지 모르니 내부에 가지고 있는 배열의 capacity만큼 다 돌아야 할 거 같아서요. 그렇다면 배열의 capacity는 default인지 아닐지 모르는데 이걸 일일히 확인하고 for문을 돌린다는 것도 이상하고요.)LinkedList 때도 문의 드린 건데 Set도 보면 toString을 따로 구현체들이 오버라이딩 하고 있지 않고 set.toString()을 찍어봐도 object에서 선언한 toString()을 가리키던데 어떻게 다음과 같이 출력이 될까요 ? System.out.println(set);[20, 10, 30]아래 질문헀던 건데 답변을 못 받아서 재질문드립니다.HashSet의 toString 코드를 보다 문의사항이 있어 질문합니다. @Override public String toString() { return "MyHashSetV2{" + "buckets=" + Arrays.toString(buckets) + ", size=" + size + ", capacity=" + capacity + '}'; }다음과 같이 되어 있고 출력을MyHashSetV2{buckets=[[Member{id='hi'}, Member{id='JPA'}], [], [], [], [], [], [Member{id='spring'}], [], [], [Member{id='java'}]], size=4, capacity=10} 이렇게 하니까 Arrays.toString(buckets) 부분이[[Member{id='hi'}, Member{id='JPA'}], [], [], [], [], [], [Member{id='spring'}], [], [], [Member{id='java'}]]이 부분일텐데 따라 들어가면 toString 오버라이딩 된 형태가 toString(Object[] a) {다음과 같고 실제 스트링으로 만드는 코드는StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0; ; i++) { b.append(String.valueOf(a[i]));이거인데요.여기서 말하는 a[i]는 LinkedList<Object>[] set의 각각의 인덱스에 위치한 LinkedList<Object> 일텐데 LinkedList나 상위의 List를 타고 들어가봐도 따로 toString 메서드를 살펴볼 수 없습니다. String.valueOf(LinkedList)가 어떻게 동작하는건가요 ? 출력물 보면 각 LinkedList안에 객체로 들어간 member의 toString을 출력하는 거 같기는 한데 LinkedList를 순차척으로 도는 코드를 확인 못하겠습니다.감사합니다.
-
해결됨비전공자의 전공자 따라잡기 - 자료구조(with JavaScript)
[숙제] minHeap 구현, maxHeap -> minHeap , minHeap -> maxHeap
minHeap 구현class MinHeap { // 최소힙 arr = []; #reheapUp(index) { if (index > 0) { const parentIndex = Math.floor((index - 1) / 2); if (this.arr[index] < this.arr[parentIndex]) { const tmp = this.arr[index]; this.arr[index] = this.arr[parentIndex]; this.arr[parentIndex] = tmp; this.#reheapUp(parentIndex); } } } insert(value) { const index = this.arr.length; this.arr[index] = value; // 마지막에 값을 넣어준다. this.#reheapUp(index); } #reHeapDown(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index if (leftIndex < this.arr.length) { const rightIndex = index * 2 + 2; const smaller = this.arr[leftIndex] < this.arr[rightIndex] ? leftIndex : rightIndex; if (this.arr[index] > this.arr[smaller]) { const temp = this.arr[index]; this.arr[index] = this.arr[smaller]; this.arr[smaller] = temp; this.#reHeapDown(smaller); } } } remove() { // root만 remove if (this.arr.length === 0) { return false; } if (this.arr.length === 1) { // 마지막 하나 남으면 pop해서 리턴해주기 return this.arr.pop(); } const root = this.arr[0]; this.arr[0] = this.arr.pop(); this.#reHeapDown(0); return root; } sort() { // 힙 정렬 const sortedArray = []; while (this.arr.length > 0) { sortedArray.push(this.remove()); } return sortedArray; } search(value) { for (let i = 0; i < this.arr.length; i++) { if (this.arr[i] === value) { return i; } } return null; } // 특정값 수정 update(value, newValue) { const index = this.search(value); if (index === null) { return false; } this.arr[index] = newValue; for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { this.#heapify(i); } } // 특정값 삭제 removeValue(value) { const index = this.search(value); if (index === null) { return false; } // 특정값의 index를 splice를 이용하여 없애버린다. this.arr.splice(index, 1); for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { // 이렇게 했을때 힙이 깨질 수 있기 떄문에 heapify 해준다 this.#heapify(i); } } transFormMaxHeap() { for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { // i가 2부터 시작 // 이렇게 했을때 힙이 깨질 수 있기 떄문에 heapify 해준다 this.#maxHeapify(i); } return this.arr; } // 특정값을 수정하거나 특정값을 삭제하거나 #heapify(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index 78의 왼쪽 5: 23 const rightIndex = index * 2 + 2; // 오른쪽 6: undefined const smaller = (this.arr[leftIndex] || Number.MAX_SAFE_INTEGER) < (this.arr[rightIndex] || Number.MAX_SAFE_INTEGER) ? leftIndex : rightIndex; if (this.arr[index] > this.arr[smaller]) { const temp = this.arr[index]; this.arr[index] = this.arr[smaller]; this.arr[smaller] = temp; this.#heapify(smaller); } } #maxHeapify(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index const rightIndex = index * 2 + 2; const bigger = (this.arr[leftIndex] || 0) > (this.arr[rightIndex] || 0) ? leftIndex : rightIndex; if (this.arr[index] < this.arr[bigger]) { const temp = this.arr[index]; this.arr[index] = this.arr[bigger]; this.arr[bigger] = temp; // 재귀 호출 해주어야 된다! this.#maxHeapify(bigger); } } }최소 힙 insertconst minheap = new MinHeap(); minheap.insert(78); minheap.insert(56); minheap.insert(45); minheap.insert(32); minheap.insert(23); minheap.insert(19); minheap.insert(8); // 결과 [8, 32, 19, 78, 45, 56, 23]결과 그림최소힙 removeconst minheap = new MinHeap(); minheap.insert(78); minheap.insert(56); minheap.insert(45); minheap.insert(32); minheap.insert(23); minheap.insert(19); minheap.insert(8); minheap.remove(); minheap.remove(); minheap.remove(); minheap.remove(); minheap.remove(); minheap.remove(); // 8 , 32, 19, 78, 45 ,56, 23 // 19, 32, 23, 78, 45, 56 // 23, 32, 56, 78, 45 // 32, 45, 56, 78 // 45, 78, 56 // 56, 78 // 78최소힙 updateconst minheap = new MinHeap(); minheap.insert(78); minheap.insert(56); minheap.insert(45); minheap.insert(32); minheap.insert(23); minheap.insert(19); minheap.insert(8); minheap.update(32, 90); // [8, 32, 19, 78, 45, 56, 23] // 결과 -> [8, 45, 19, 78, 90, 56, 23]최소힙 removeValueconst minheap = new MinHeap(); minheap.insert(78); minheap.insert(56); minheap.insert(45); minheap.insert(32); minheap.insert(23); minheap.insert(19); minheap.insert(8); minheap.removeValue(19); // [8, 45, 19, 78, 90, 56, 23] // 결과 -> [8, 45, 23, 90, 56, 78]최소힙 -> 최대힙const minheap = new MinHeap(); minheap.insert(78); minheap.insert(56); minheap.insert(45); minheap.insert(32); minheap.insert(23); minheap.insert(19); minheap.insert(8); console.log(minheap.transFormMaxHeap()); // [ 8, 32, 19, 78, 45, 56, 23 ] // 결과 -> [78, 45, 56, 32, 8, 19, 23]최대힙 -> 최소힙class MaxHeap { arr = []; #reheapUp(index) { if (index > 0) { const parentIndex = Math.floor((index - 1) / 2); if (this.arr[index] > this.arr[parentIndex]) { // 값 바꾸기 const tmp = this.arr[index]; this.arr[index] = this.arr[parentIndex]; this.arr[parentIndex] = tmp; this.#reheapUp(parentIndex); } } } insert(value) { const index = this.arr.length; this.arr[index] = value; // 마지막에 값을 넣어준다. this.#reheapUp(index); } #reHeapDown(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index if (leftIndex < this.arr.length) { // 만약에 왼쪽 인덱스가 총 배열의 길이보다 작은경우 const rightIndex = index * 2 + 2; const bigger = this.arr[leftIndex] > this.arr[rightIndex] ? leftIndex : rightIndex; if (this.arr[index] < this.arr[bigger]) { const temp = this.arr[index]; this.arr[index] = this.arr[bigger]; this.arr[bigger] = temp; this.#reHeapDown(bigger); } } } remove() { // root만 remove if (this.arr.length === 0) { return false; } if (this.arr.length === 1) { // 마지막 하나 남으면 pop해서 리턴해주기 return this.arr.pop(); } const root = this.arr[0]; this.arr[0] = this.arr.pop(); this.#reHeapDown(0); return root; } sort() { // 힙 정렬 const sortedArray = []; while (this.arr.length > 0) { sortedArray.push(this.remove()); } return sortedArray; } search(value) { for (let i = 0; i < this.arr.length; i++) { if (this.arr[i] === value) { return i; } } return null; } // 특정값 수정 update(value, newValue) { const index = this.search(value); if (index === null) { return false; } this.arr[index] = newValue; for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { this.#heapify(i); } } // 특정값 삭제 removeValue(value) { const index = this.search(value); if (index === null) { return false; } // 특정값의 index를 splice를 이용하여 없애버린다. this.arr.splice(index, 1); for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { // 이렇게 했을때 힙이 깨질 수 있기 떄문에 heapify 해준다 this.#heapify(i); } } transFromMinHeap() { for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) { // i가 2부터 시작 // 이렇게 했을때 힙이 깨질 수 있기 떄문에 heapify 해준다 this.#minHeapify(i); } return this.arr; } // 특정값을 수정하거나 특정값을 삭제하거나 #heapify(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index const rightIndex = index * 2 + 2; const bigger = (this.arr[leftIndex] || 0) > (this.arr[rightIndex] || 0) ? leftIndex : rightIndex; if (this.arr[index] < this.arr[bigger]) { const temp = this.arr[index]; this.arr[index] = this.arr[bigger]; this.arr[bigger] = temp; this.#heapify(bigger); } } // 특정값을 수정하거나 특정값을 삭제하거나 #minHeapify(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index 78의 왼쪽 5: 23 const rightIndex = index * 2 + 2; // 오른쪽 6: undefined const smaller = (this.arr[leftIndex] || Number.MAX_SAFE_INTEGER) < (this.arr[rightIndex] || Number.MAX_SAFE_INTEGER) ? leftIndex : rightIndex; if (this.arr[index] > this.arr[smaller]) { const temp = this.arr[index]; this.arr[index] = this.arr[smaller]; this.arr[smaller] = temp; this.#minHeapify(smaller); } } } const heap = new MaxHeap(); heap.insert(8); heap.insert(19); heap.insert(23); heap.insert(32); heap.insert(45); heap.insert(56); heap.insert(78); console.log(heap.transFormMinHeap()); // [78, 32, 56, 8, 23, 19, 45] // -> 결과 [8, 23, 19, 32, 78, 56, 45] 질문1) maxheap(minheap) 코드 구현시 heapify 메서드에서 재귀호출 되어야 되지 않는가요?강의에서는 heapify 메서드 구현시 재귀 호출 부분이 빠져있는것 같아서 질문 드립니다. 아니라면 죄송합니다.#heapify(index) { const leftIndex = index * 2 + 1; // 왼쪽 Index const rightIndex = index * 2 + 2; const bigger = (this.arr[leftIndex] || 0) > (this.arr[rightIndex] || 0) ? leftIndex : rightIndex; if (this.arr[index] < this.arr[bigger]) { const temp = this.arr[index]; this.arr[index] = this.arr[bigger]; this.arr[bigger] = temp; // 여기 빠진것 같습니다! this.#heapify(bigger); } }