Skip to content

Conversation

@uyeon0
Copy link
Collaborator

@uyeon0 uyeon0 commented Oct 21, 2025

User description

오늘도 멋져요 👍✨


PR Type

Enhancement


Description

  • 프로그래머스 미로 탈출 문제 - BFS 2번 활용한 구현

  • 프로그래머스 다단계 칫솔 판매 - 트리 구조 재귀 구현

  • README.md에 새로운 문제 해결 목록 추가


@uyeon0 uyeon0 added the programmers Programmers 문제 풀이 label Oct 21, 2025
@github-actions
Copy link

PR Reviewer Guide 🔍

🧪 PR contains tests
⚡ Recommended focus areas for review

성능 개선 가능성

BFS 구현에서 Map 대신 Array를 사용한 Queue 구현이 더 효율적일 수 있습니다. Map의 set/delete 연산은 Array의 push/shift보다 오버헤드가 큽니다.

class Queue {
  queue = new Map();
  head = 0;
  tail = 0;

  constructor() {}

  get size() {
    return this.tail - this.head;
  }

  enqueue(element) {
    this.queue.set(this.tail++, element);
  }

  dequeue() {
    const ret = this.queue.get(this.head);
    if (!ret) {
      return undefined;
    }
    this.queue.delete(this.head++);
    return ret;
  }

  isEmpty() {
    return this.head === this.tail;
  }
}
메모리 최적화

Map을 두 개 사용하는 대신 단일 Map에 {parent, index} 객체를 저장하여 메모리 사용량을 줄일 수 있습니다. 현재 구조는 동일한 정보를 중복 저장하고 있습니다.

const index = new Map(); // key: 판매원 이름, value: enroll과 answer 상의 인덱스
const parent = new Map(); // key: 자식 노드 판매원 이름, value: 부모 노드 판매원 이름

// Map 초기화
for (let idx = 0; idx < enroll.length; idx++) {
  index.set(enroll[idx], idx);
  if (referral[idx] !== "-") {
    // 추천인이 있는 경우에만 저장한다.
    parent.set(enroll[idx], referral[idx]);
  }
}
엣지 케이스 처리

분배금이 1원 미만일 때의 처리가 명시적이지 않습니다. 소수점 처리와 관련된 엣지 케이스에서 문제가 발생할 수 있습니다.

function distribute(name, currentProfit) {
  if (name === undefined || currentProfit <= 0) {
    // 분배 못함
    return;
  }
  const distributedProfit = Math.floor(currentProfit * 0.1);
  const retainedProfit = currentProfit - distributedProfit;

  // 남은 금액을 현재 판매원에게 준다.
  answer[index.get(name)] += retainedProfit;
  // 상위 추천인이 없거나 분배할 이익이 없다면 분배를 중단한다.
  if (parent.get(name) === undefined || distributedProfit === 0) {
    return;
  }
  // 남은 이익을 상위 판매원이 다시 분배한다.
  distribute(parent.get(name), distributedProfit);
}

@github-actions
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
재귀 함수 로직 개선

재귀 함수의 종료 조건을 더 명확하게 정리하고, 조건문을 단순화할 수 있습니다. 또한 조기 반환(early return)을 활용하여 코드의 가독성을
높일 수 있습니다.

Programmers/Level3/77486_다단계_칫솔_판매.js [33-49]

 function distribute(name, currentProfit) {
-  if (name === undefined || currentProfit <= 0) {
-    // 분배 못함
-    return;
-  }
+  if (!name || currentProfit <= 0) return;
+
   const distributedProfit = Math.floor(currentProfit * 0.1);
   const retainedProfit = currentProfit - distributedProfit;
-
-  // 남은 금액을 현재 판매원에게 준다.
+  
   answer[index.get(name)] += retainedProfit;
-  // 상위 추천인이 없거나 분배할 이익이 없다면 분배를 중단한다.
-  if (parent.get(name) === undefined || distributedProfit === 0) {
-    return;
-  }
-  // 남은 이익을 상위 판매원이 다시 분배한다.
-  distribute(parent.get(name), distributedProfit);
+  
+  const parentName = parent.get(name);
+  if (!parentName || distributedProfit === 0) return;
+  
+  distribute(parentName, distributedProfit);
 }
Suggestion importance[1-10]: 5

__

Why: 조기 반환과 조건문 단순화로 코드가 더 간결해지고 가독성이 향상됨. parentName 변수 도입으로 의도가 더 명확해짐. 하지만 기능적 변화는 없음.

Low
큐 구현 단순화

Map을 사용한 큐 구현은 불필요하게 복잡합니다. 배열을 사용하면 더 간단하고 직관적으로 구현할 수 있습니다. shift()push()를 사용하면
큐의 기본 동작을 쉽게 구현할 수 있습니다.

Programmers/Level2/159993_미로_탈출.js [18-45]

 class Queue {
-  queue = new Map();
-  head = 0;
-  tail = 0;
-
-  constructor() {}
+  constructor() {
+    this.items = [];
+  }
 
   get size() {
-    return this.tail - this.head;
+    return this.items.length;
   }
 
   enqueue(element) {
-    this.queue.set(this.tail++, element);
+    this.items.push(element);
   }
 
   dequeue() {
-    const ret = this.queue.get(this.head);
-    if (!ret) {
-      return undefined;
-    }
-    this.queue.delete(this.head++);
-    return ret;
+    return this.items.shift();
   }
 
   isEmpty() {
-    return this.head === this.tail;
+    return this.items.length === 0;
   }
 }
Suggestion importance[1-10]: 4

__

Why: 배열 기반 큐 구현이 더 간단할 수 있지만, Map 기반 구현도 유효하며 메모리 관리 측면에서 장점이 있을 수 있음. 제안된 변경은 스타일 선호도에 가까움.

Low

@yoouyeon
Copy link
Owner

/ask "Map의 delete 연산이 Array의 shift보다 오버헤드가 큰 이유가 무엇인가요?"

@github-actions
Copy link

Ask

map의 delete 연산이 array의 shift보다 오버헤드가 큰 이유가 무엇인가요?

Answer:

Map의 delete 연산이 Array의 shift보다 오버헤드가 큰 이유를 설명하겠습니다.

  1. Map의 delete 연산:
  • Map은 해시 테이블 기반의 자료구조입니다.
  • delete 연산 시 내부적으로 해시 충돌 해결을 위한 체이닝이나 개방 주소법 등의 메커니즘을 처리해야 합니다.
  • 해시 테이블의 load factor를 관리하기 위한 추가 작업이 필요할 수 있습니다.
  • 키의 해시값을 계산하고 해당 버킷을 찾는 과정이 필요합니다.
  1. Array의 shift 연산:
  • 배열의 첫 번째 요소를 제거하고 나머지 요소들을 한 칸씩 앞으로 이동시키는 단순한 작업입니다.
  • 메모리상에서 연속된 공간을 사용하므로, 요소들의 이동이 효율적으로 이루어집니다.
  • 추가적인 해시 계산이나 충돌 처리가 필요하지 않습니다.

따라서 PR의 Queue 구현에서 Map을 사용하는 것보다 Array를 사용하는 것이 더 효율적일 수 있습니다. 단, 큐의 크기가 매우 크고 dequeue 연산이 매우 빈번한 경우에는 circular queue와 같은 다른 구현 방식을 고려하는 것이 좋습니다.

@yoouyeon yoouyeon added the ready-to-merge pr을 머지해주세요 label Oct 21, 2025
@uyeon0 uyeon0 merged commit f4cb08e into main Oct 21, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

programmers Programmers 문제 풀이 ready-to-merge pr을 머지해주세요

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants