JavaScript/Algorithm

3. 문제 해결 접근법

code10 2023. 3. 13. 19:16

Udemy - 【한글자막】 JavaScript 알고리즘 & 자료구조 마스터클래스 :: 섹션 4 문제 해결 접근법

HOW DO YOU IMPROVE?

  1. Devise a plan for solving problems
  2. Master common problem solving patterns

PROBLEM SOLVING

  • Understand the Problem
  • Explore Concrete Examples
  • Break It Down
  • Solve/Simplify
  • Look Back and Refactor

 

1. UNDERSTAND THE PROBLEM 문제의 이해

  1. Can I restate the problem in my own words?
  2. What are the inputs that go into the problem?
  3. What are the outputs that should come from the solution to the problem?
  4. Can the outputs be determined from the inputs? In other words, do I have enough information to solve the problem? (You may not be able to answer this question until you set about solving the problem. That's okay; it's still worth considering the question at this early stage.)
  5. How should I label the important pieces of data that are a part of the problem?

 

=> 내 방식으로 문제 해석

=> 어떤 입력값을 갖는가?

=> 어떤 출력값이 나와야 하는가?

=> 입력값을 알면 해당 정보만 사용해서 예상되는 출력값이 반환될까? 때로는 파악할 수 있을 때까지 기다려야 하는 경우도 있다.

=> 문제의 일부인 데이터의 중요한 부분에 어떻게 라벨을 지정할 수 있을까? 이 질문은 이 문제에서 정말 중요한 것이 무엇인가 라는 것. 뭐라고 라벨을 지정할지 어떤 용어를 사용해야 좋을지 말이죠.

2. EXPLORE EXAMPLES 구체적 예제들

  • Start with Simple Examples
  • Progress to More Complex Examples
  • Explore Examples with Empty Inputs
  • Explore Examples with Invalid Inputs
 제가 면접을 진행 중이거나 수강생들이 모의 면접을 할 때 저는 이렇게 말합니다. 이제 문제를 다시 여러분 방식대로 생각해 보았고 문제를 이해했으니 이번에는 입력값과 출력값의 순서대로 예시를 두세 개 작성해 보라고 말이죠.
가장 쉬운 사용 사례와 같은 예시들부터 더 복잡한 예시들로 진행하시면 되겠습니다.
그럼 경계 조건은 어떨까요?
빈 입력값이 있는 예제를 살펴보는 것은 특히 유효하지 않은 입력값이 주어진 면접 상황에서 문제를 어떻게 해결해야 할지 해결 능력을 갖출 수 있도록 해줍니다. 이처럼 실제 작업 환경에서는 더 유용하다 할 수 있겠습니다.
사용자가 유효하지 않은 값을 입력하면 어떻게 될지를 항상 생각할 수 있어야 합니다.

3. BREAK IT DOWN 세부 분석

Explicitly write out the steps you need to take.

This forces you to think about the code you'll write before you write it, and helps you catch any lingering conceptual issues or misunderstandings before you dive in and have to worry about details (e.g. language syntax) as well.

문제를 세분화하는 건 아주 중요하기에 여러분이 밟아야 할 단계들을 명확하게 작성해 보시는 걸 추천합니다.
아주 세세하게 작성할 필요도 모든 라인마다 작성할 필요도 없습니다. 그저 해결책의 기본적인 구성 요소만 작성하시면 됩니다.
그럼으로써 코드를 실제로 입력하기 전에 한 번 생각해 볼 수 있게 해줍니다. 자유분방하게 코드를 대충 떠오르는대로 입력하는 게 아니라 감이 잡히지 않거나 이해되지 않는 부분들을 파악하게 하거나 이해할 수 있게 해줍니다. 그래서 문제를 세분화하는 것을 추천하는 겁니다.
 

4. SOLVE THE PROBLEM 해결

If you can't...

SOLVE A SIMPLER PROBLEM!

SIMPLIFY 또는 단순화

  • Find the core difficulty in what you're trying to do
  • Temporarily ignore that difficulty
  • Write a simplified solution
  • Then incorporate that difficulty back in

5. LOOK BACK & REFACTOR 되돌아 보기와 리펙터

Congrats on solving it, but you're not done!

지저분해도 괜찮겠지만 그래도 코드를 향상시키고자 노력하는 것이 정말 중요합니다.
시간을 내어 코드를 살펴보고, 되돌아보고, 성찰하지 않는다면 좋은 기회를 놓치게 될 겁니다.

각 구성요소를 한 줄씩 살펴 보면서 마음에 들지 않는 부분이나, 코드의 형태, 해석 방법, 또 이해하기 얼마나 쉬운지에 대해 이야기를 하라는 의미입니다.

대부분의 사람들이 중요하게 여기는 것은 분명히 코드를 볼 때의 효율성입니다.
그러나 대체로 효율성과 가독성이라는 두 기둥 사이에 균형을 맞춰야 할 필요가 있습니다.

REFACTORING QUESTIONS

  • Can you check the result? 결과를 확인할 수 있나요?
  • Can you derive the result differently? 결과를 다른 방식으로 도출할 수 있나요? (문제에 대한 해결책이 하나만 있는 경우는 드물기 때문에 이런 질문이 가능하겠죠.)
  • Can you understand it at a glance? 해결한 이 방법 외에 생각나는 다른 접근 방식이 있나요?
  • Can you use the result or method for some other problem? 앞서 생각하지 못한 다른 방법을 적용할 수 있나요? 
  • Can you improve the performance of your solution? 해결책의 성능을 향상시킬 수 있나요?
  • Can you think of other ways to refactor? 코드를 향상시킬 수 있는 다른 방법을 떠올릴 수 있나요?
  • How have other people solved this problem? 다른 사람들은 이 문제를 어떻게 해결하나요?

 

function charCount(str) {
    var obj = {};
    for (var i = 0; i < str.length; i++){
        var char = str[i].toLowerCase();
        if(/[a-z0-9]/.test(char)){
            if (obj[char] > 0){
                obj[char]++;
            } else {
                obj[char] = 1;
            }
        }
    }
     return obj;
}

||

refactor

반복문: for (let i=0; ...) => for... of 구문 (추가 선언 필요 없다)

숫자 or 문자인지 확인 : 정규식보다 charCodeAt 이용이 빠르다고

전부 소문자로 바꾸는 작업: 어떤 단계에서 시행할 것인가 고민 필요

문자열 요소가 있으면 ++ , 없으면 1 : || 활용하여 가독성 등 개선

V

function charCount(str) {
    var obj = {};
    for (var char of str){
        if(isAlphaNumeric(char)){
            char = char.toLowerCase();
            obj[char] = ++obj[char] || 1;
        }
    }
    return obj;
}

function isAlphaNumeric(char){
    var code = char.charCodeAt(0);
    if (!(code > 47 && code < 58) && //numeric (0-9)
        !(code > 64 && code < 91) && //upper alpha (A-Z)
        !(code > 96 && code < 123)){ //lower alpha (a-z)
        return false;
        }
    return true;
}

charCount("hello"); // {h: 1, e: 1, l: 2, o: 1}

charCount("hel  33 H2lo"); // {2: 1, 3: 2, h: 2, e: 1, l: 2, o: 1}