Algorithm Cheat Sheet

1. 기본 문제 / 세 수 중 최솟값

  • 핵심 내용 정리

    • 주어진 세 수 a, b, c 중 가장 작은 값을 if문을 통해 조건을 비교하며 찾는 문제입니다.
    • 문제는 JavaScript 조건문 사용을 연습하는 데 중점을 두며, 정렬 함수 없이 오직 if문을 통해 최소값을 찾도록 설계되었습니다.
  • 알고리즘 과정:

    1. a와 b 중 작은 값을 answer에 저장.
    2. c와 answer를 비교하여 더 작은 값을 최종 최소값으로 갱신.
    3. answer를 리턴하여 최솟값 출력.
function findMin(a, b, c) {
  let answer;

  // 첫 번째 비교: a와 b 중 작은 값을 answer에 할당
  if (a < b) {
    answer = a;
  } else {
    answer = b;
  }

  // 두 번째 비교: c와 answer 중 작은 값을 최종 answer에 할당
  if (c < answer) {
    answer = c;
  }

  return answer;
}

// 예제 실행
const min = findMin(6, 5, 11);
console.log(min); // 출력: 5

2. 기본 문제 / 삼각형 판별하기

삼각형을 만들기 위한 조건은 가장 긴 막대의 길이가 나머지 두 막대의 길이 합보다 작아야 합니다. 이를 위해 최대값 찾기와 조건문을 이용하여 판별하며, if문과 sum 변수로 간단한 계산을 통해 판별합니다.

function canFormTriangle(a, b, c) {
  let max;
  
  // Step 1: a와 b 중 큰 값을 max에 할당
  if (a > b) {
    max = a;
  } else {
    max = b;
  }
  
  // Step 2: c와 max를 비교하여 가장 큰 값으로 max 갱신
  if (c > max) {
    max = c;
  }
  
  // Step 3: 총합 계산 후 삼각형 가능 여부 판단
  const sum = a + b + c;
  let answer = "YES";
  
  if (sum - max <= max) {
    answer = "NO";
  }
  
  return answer;
}

// 예제 실행
console.log(canFormTriangle(6, 7, 11)); // 출력: YES
console.log(canFormTriangle(13, 33, 17)); // 출력: NO

3. 기본 문제 / 연필개수

주어진 문제는 학생 수 n에 따라 필요한 연필 다스 수를 계산하는 것으로, 한 다스는 12자루로 구성됩니다. 필요한 다스 수는 학생 수를 12로 나누었을 때 나머지가 있으면 추가 다스를 더하여 계산됩니다. Math.ceil() 함수를 이용해 소수점을 올림하여 전체 다스 수를 간단히 구할 수 있습니다.

function calculateDozens(n) {
  // 학생 수 n에 따른 필요한 연필 다스 수 계산
  return Math.ceil(n / 12);
}

// 예제 실행
console.log(calculateDozens(25));  // 출력: 3
console.log(calculateDozens(178)); // 출력: 15

4. 기본 문제 / 1부터 N까지의 합

이 문제는 1부터 n까지의 정수를 모두 더하여 결과를 출력하는 것으로, for문을 이용하여 반복문으로 합을 계산합니다. answer 변수에 반복마다 i 값을 누적하여 최종 합을 구합니다.

function sumUpToN(n) {
  let answer = 0;
  
  for (let i = 1; i <= n; i++) {
    answer += i; // answer에 i 값을 누적
  }
  
  return answer;
}

// 예제 실행
console.log(sumUpToN(6));  // 출력: 21
console.log(sumUpToN(12)); // 출력: 78

5. 기본 문제 / 최솟값 구하기

주어진 문제는 배열에서 최소값을 찾는 것으로, for문을 이용하여 배열을 순회하며 각 요소와 min 변수를 비교해 가장 작은 값을 찾아냅니다. 첫 번째 비교에서 작은 값을 적용하기 위해 min을 매우 큰 값으로 초기화합니다.

function findMinimum(arr) {
  let min = Number.MAX_SAFE_INTEGER; // 초기값을 매우 큰 값으로 설정
  
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] < min) {
      min = arr[i]; // arr[i]가 min보다 작으면 min을 갱신
    }
  }
  
  return min;
}

// 예제 실행
const numbers = [5, 7, 1, 3, 2, 9, 10];
console.log(findMinimum(numbers)); // 출력: 1

기본 문제 / 내장함수로 최솟값, 최댓값 구하기

배열에서 최소값과 최대값을 찾기 위해 Math.min()과 Math.max() 함수를 사용합니다. 이때, spread operator를 사용하여 배열을 개별 인자로 펼쳐 Math.min()과 Math.max() 함수에 전달할 수 있습니다. 이 외에도 apply 메서드를 통해 배열을 함수에 인자로 전달할 수 있습니다.

function findMinAndMax(arr) {
  // 배열에서 최소값과 최대값을 각각 구함
  const min = Math.min(...arr);
  const max = Math.max(...arr);

  console.log("Minimum value:", min); // 최소값 출력
  console.log("Maximum value:", max); // 최대값 출력

  return { min, max };
}

// 예제 실행
const numbers = [5, 7, 1, 3, 2, 9, 10];
findMinAndMax(numbers); // 출력: Minimum value: 1, Maximum value: 10

6. 기본 문제 / 홀수

주어진 배열에서 홀수를 찾아 그 합과 최소값을 구하는 문제입니다. for...of문을 사용하여 배열을 탐색하면서 홀수 조건을 만족하는 요소를 누적하여 합산하고, 동시에 최소값을 갱신합니다. 최종적으로, 두 결과를 배열로 반환합니다.

function findOddSumAndMin(arr) {
  let sum = 0;
  let min = Number.MAX_SAFE_INTEGER;
  
  for (let x of arr) {
    if (x % 2 === 1) {  // 홀수인지 확인
      sum += x;          // 홀수인 경우 누적 합
      if (x < min) {     // 홀수 중 최소값 갱신
        min = x;
      }
    }
  }
  
  return [sum, min];
}

// 예제 실행
const numbers = [12, 77, 38, 41, 53, 92, 85];
console.log(findOddSumAndMin(numbers)); // 출력: [256, 41]

7. 기본 문제 / 10부제

10부제 문제는 날짜의 1의 자리가 주어진 day 값과 일치하는 자동차 번호의 1의 자리를 확인하여 운행 제한 위반 여부를 확인하는 문제입니다. 각 자동차 번호의 1의 자리를 10으로 나눈 나머지로 얻고, 이를 day와 비교하여 위반 차량의 개수를 세어 출력합니다.

function countViolatingCars(arr, day) {
  let answer = 0;

  for (let x of arr) {
    if (x % 10 === day) {  // 자동차 번호의 1의 자리가 day와 같은지 확인
      answer++;           // 위반 차량 카운트 증가
    }
  }

  return answer;
}

// 예제 실행
const cars = [23, 53, 33, 44, 73, 12, 93];
const day = 3;
console.log(countViolatingCars(cars, day)); // 출력: 5

기본 문제 / forEach, map, filter, reduce 메서드 작동원리

JavaScript 배열 메서드 forEach, map, filter, reduce는 고차 함수로, 각각 배열의 반복, 변환, 필터링, 누적을 수행합니다. 각 메서드는 배열을 순회하면서 콜백 함수를 반복 호출하여 각 요소에 접근하며, 동작 방식과 반환값이 다릅니다.

  • 메서드별 기능 개요:
    1. forEach: 배열의 각 요소에 대해 주어진 작업을 수행하지만, 새로운 배열이나 값은 반환하지 않음.
    2. map: 배열의 각 요소를 변환하여 새로운 배열을 반환하며, 원본 배열과 길이가 동일.
    3. filter: 조건을 만족하는 배열 요소만 포함하는 새 배열을 반환, 길이는 조건에 따라 달라질 수 있음.
    4. reduce: 배열 요소를 누적하여 단일 값을 반환하며, 주로 합산, 곱셈 등의 누적 연산에 사용됨.
const numbers = [1, 2, 3, 4, 5];

// forEach: 각 요소를 콘솔에 출력
numbers.forEach((num, index) => {
  console.log(`Index ${index}: ${num}`);
});

// map: 각 요소를 제곱하여 새로운 배열 생성
const squares = numbers.map(num => num ** 2);
console.log("Squares:", squares); // [1, 4, 9, 16, 25]

// filter: 짝수만 포함하는 새로운 배열 생성
const evens = numbers.filter(num => num % 2 === 0);
console.log("Evens:", evens); // [2, 4]

// reduce: 모든 요소의 합 계산
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log("Sum:", sum); // 15

8. 기본 문제 / 일곱난쟁이

난쟁이 문제는 9명의 난쟁이 키 중에서 가짜 두 명을 찾아 배열에서 제거한 후 나머지 7명의 난쟁이 키만 출력하는 문제입니다. 9명의 난쟁이 키 합계에서 가짜 두 명의 키를 뺀 값이 100이 될 때 그 두 명을 가짜로 판별합니다. splice 메서드를 사용하여 가짜 난쟁이를 배열에서 제거하고, 이중 for문을 통해 모든 쌍을 비교하여 가짜 난쟁이를 식별합니다.

  • 알고리즘 과정:
    1. 9명의 난쟁이 키 합을 reduce로 계산.
    2. 이중 for문으로 난쟁이 쌍을 조합하여 두 명의 난쟁이 키 합을 원래 합계에서 빼기.
    3. 결과가 100이 될 경우 해당 두 명을 splice로 배열에서 제거.
    4. 나머지 난쟁이 키 배열을 반환.
function findSevenDwarfs(arr) {
  const totalSum = arr.reduce((acc, val) => acc + val, 0);

  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (totalSum - (arr[i] + arr[j]) === 100) {
        arr.splice(j, 1); // j 먼저 삭제
        arr.splice(i, 1); // i 삭제
        return arr;       // 가짜 난쟁이 제거 후 반환
      }
    }
  }
}

// 예제 실행
const dwarfs = [20, 7, 23, 19, 10, 15, 25, 8, 13];
console.log(findSevenDwarfs(dwarfs)); // 출력: [20, 7, 23, 19, 10, 8, 13]

기본 문제 / 일곱난쟁이 오류 수정 영상

일곱 난쟁이 문제는 9명의 난쟁이 키 중에서 가짜 두 명을 제거한 후, 나머지 7명의 난쟁이 키를 출력하는 문제입니다. 기존 코드에서 모든 난쟁이 쌍을 탐색하여 첫 번째로 발견된 가짜 난쟁이 쌍을 식별할 때 반복문을 멈추는 break 처리가 누락되었습니다. 이를 위해 플래그 변수를 사용하여 가짜 난쟁이를 찾은 후 이중 반복문을 종료하게 합니다.

  • 알고리즘 과정:
    1. 9명의 난쟁이 키 합을 reduce로 계산.
    2. 이중 for문으로 난쟁이 쌍을 조합하여 두 명의 난쟁이 키 합을 원래 합계에서 빼기.
    3. 결과가 100이 될 경우 플래그 변수를 설정하고 반복문을 종료.
    4. 나머지 난쟁이 키 배열을 반환.
function findSevenDwarfs(arr) {
  const totalSum = arr.reduce((acc, val) => acc + val, 0);
  let flag = 0; // 플래그 변수

  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (totalSum - (arr[i] + arr[j]) === 100) {
        arr.splice(j, 1); // j를 먼저 삭제
        arr.splice(i, 1); // 그 다음 i 삭제
        flag = 1;         // 가짜 난쟁이를 찾았음을 표시
        break;            // 내부 반복문 종료
      }
    }
    if (flag === 1) break; // 외부 반복문 종료
  }

  return arr;
}

// 예제 실행
const dwarfs = [22, 7, 21, 19, 10, 15, 25, 8, 13];
console.log(findSevenDwarfs(dwarfs)); // 출력 예: [22, 7, 10, 15, 25, 8, 13]

9. 기본 문제 / A를 #으로

문자열 탐색 문제는 주어진 문자열에서 특정 문자를 찾아서 변환하는 문제입니다. 이 문제에서는 문자열 내의 대문자 A를 모두 #으로 변환해야 합니다. for...of 문을 사용하여 문자 하나씩 검사하며 변환하거나, replace와 정규 표현식을 사용하여 변환하는 방식으로 해결할 수 있습니다. 문자열은 값 복사 방식으로 작동하여, 문자열 조작 시 원본 문자열이 변경되지 않으며 새 변수에 결과를 저장해야 합니다.

  • 알고리즘 과정:
    1. 문자열 내 각 문자를 순회하여 A를 #으로 변환하며 결과를 누적.
    2. replace 메서드와 정규식을 사용하여 A를 전역 치환(g 플래그)하는 방식으로 변환.
    3. 최종 변환된 문자열을 반환.
function replaceAwithHash(str) {
  let answer = "";

  // 문자열 내의 각 문자를 검사하여 'A'를 '#'으로 변환
  for (let char of str) {
    if (char === 'A') {
      answer += '#';
    } else {
      answer += char;
    }
  }
  
  // 또는, replace를 사용한 해결 방법
  // let answer = str.replace(/A/g, "#");

  return answer;
}

// 예제 실행
const inputStr = "BANANA";
console.log(replaceAwithHash(inputStr)); // 출력: "B#N#N#"

10. 기본 문제 / 문자 찾기

이 문제는 주어진 문자열에서 특정 문자가 몇 번 등장하는지 확인하는 문제입니다. 문자열 탐색 방식에는 반복문과 조건문을 사용하거나, split 메서드를 통해 특정 문자를 구분자로 배열화한 뒤 개수를 계산하는 방법이 있습니다.

  • 첫 번째 방법: for...of 문으로 문자열을 순회하면서 주어진 문자와 일치할 때마다 카운트를 증가시킵니다.

  • 두 번째 방법: split 메서드를 사용하여 문자를 구분자로 문자열을 분리하고, 배열의 길이에서 1을 빼 최종 개수를 구합니다. 이 방법은 문자열의 마지막에 구분자가 있을 경우 빈 문자열이 포함되므로, 이 점을 고려해야 합니다.

  • 알고리즘 과정:

    1. 문자열을 순회하여 주어진 문자와 일치할 때마다 카운트를 증가.
    2. split 메서드로 문자를 구분자로 분리해 배열화하고, 배열 길이에서 1을 빼 개수 확인.
function countCharacterOccurrences(str, char) {
  let answer = 0;

  // 방법 1: for...of 문과 조건문을 사용한 문자 카운팅
  for (let x of str) {
    if (x === char) {
      answer++;
    }
  }
  
  // 또는 방법 2: split 메서드를 사용하여 문자 카운팅
  // answer = str.split(char).length - 1;

  return answer;
}

// 예제 실행
const inputStr = "COMPUTER PROGRAMMING";
const searchChar = "R";
console.log(countCharacterOccurrences(inputStr, searchChar)); // 출력: R의 개수, 예를 들어 3

11. 기본 문제 / 대문자 찾기

이 문제는 주어진 문자열에서 대문자 개수를 찾는 문제로, 대문자 확인 방식에 따라 다양한 접근이 가능합니다.

  1. toUpperCase 메서드 활용: 문자마다 toUpperCase로 대문자로 변환한 뒤 원래 문자와 비교하여 대문자 여부 확인.
  2. ASCII 코드 사용: charCodeAt 메서드로 ASCII 값을 얻어 대문자 범위(65-90)에 포함되는지 확인.

위 방법으로 특정 조건에 맞는 문자가 있을 때 카운트를 증가시킵니다.

  • 알고리즘 과정:
    1. 문자열을 순회하며 문자 하나씩 대문자인지 확인합니다.
    2. 대문자일 경우 카운트를 증가합니다.
    3. 최종 카운트를 반환합니다.
function countUppercaseLetters(str) {
  let answer = 0;

  // 방법 1: toUpperCase를 이용한 대문자 탐색
  for (let x of str) {
    if (x === x.toUpperCase() && x.match(/[A-Z]/)) {
      answer++;
    }
  }

  // 또는 방법 2: ASCII 코드 범위를 사용한 대문자 탐색
  // for (let x of str) {
  //   const num = x.charCodeAt(0);
  //   if (num >= 65 && num <= 90) {
  //     answer++;
  //   }
  // }

  return answer;
}

// 예제 실행
const inputStr = "KoreaTimesGreat";
console.log(countUppercaseLetters(inputStr)); // 출력: 대문자의 개수, 예를 들어 3

12. 기본 문제 / 대문자로 통일

이 문제는 문자열에서 모든 소문자를 대문자로 변환하는 문제입니다. 두 가지 방법이 있으며 각각의 원리는 다음과 같습니다:

  1. toUpperCase 메서드 사용:

    • 각 문자를 순회하며 toUpperCase를 통해 대문자로 변환 후 결과에 누적.
  2. ASCII 코드로 변환:

    • 각 문자의 ASCII 값을 확인하여 소문자 범위(97~122)에 해당하면 ASCII 값에서 32를 빼 대문자로 변환.
    • String.fromCharCode로 숫자를 문자로 변환하여 최종 문자열에 누적.
  • 알고리즘 과정:
    1. 문자열을 순회하며 소문자인지 확인.
    2. 소문자일 경우 대문자로 변환하여 결과에 누적.
    3. 최종 변환된 문자열을 반환.
function convertToUppercase(str) {
  let answer = '';

  // 방법 1: toUpperCase를 이용한 변환
  for (let x of str) {
    answer += x.toUpperCase();
  }

  // 또는 방법 2: ASCII 코드를 이용한 변환
  // for (let x of str) {
  //   const num = x.charCodeAt(0);
  //   if (num >= 97 && num <= 122) { // 소문자 ASCII 범위
  //     answer += String.fromCharCode(num - 32);
  //   } else {
  //     answer += x;
  //   }
  // }

  return answer;
}

// 예제 실행
const inputStr = "It is time to study";
console.log(convertToUppercase(inputStr)); // 출력: 모두 대문자로 변환된 문자열, 예를 들어 "IT IS TIME TO STUDY"

13. 기본 문제 / 대소문자변환

이 문제는 문자열을 모두 대문자로 변환하거나 대문자/소문자를 반대로 변환하는 문제입니다. 주어진 문자열에서 모든 소문자는 대문자로, 대문자는 소문자로 변환하는 두 가지 방법이 있습니다:

  1. toUpperCase를 이용한 한방 해결법:

    • 대소문자 구분 없이 모든 문자를 대문자로 변환할 때 사용.
    • 예시: s.toUpperCase()는 모든 문자를 한 번에 대문자로 변환.
  2. 대소문자 변환 로직을 활용한 변환:

    • 각 문자를 순회하며 소문자는 대문자로, 대문자는 소문자로 변환.
    • 조건문을 통해 toUpperCase와 toLowerCase를 적용하여 변환 수행.
function switchCase(str) {
  let answer = '';

  // 문자열을 순회하며 각 문자에 대해 조건 처리
  for (let x of str) {
    if (x === x.toUpperCase()) {
      // 대문자는 소문자로 변환하여 추가
      answer += x.toLowerCase();
    } else {
      // 소문자는 대문자로 변환하여 추가
      answer += x.toUpperCase();
    }
  }

  return answer;
}

// 예제 실행
const inputStr = "It is time to study";
console.log(switchCase(inputStr)); // 출력: iT IS TIME TO STUDY

14. 기본 문제 / 가장 긴 문자열

이 문제는 여러 문자열 중 가장 긴 문자열을 찾는 문제입니다. length 속성을 사용하여 각 문자열의 길이를 확인하고 최대 길이 값을 유지하면서 길이가 더 긴 문자열을 찾을 때마다 업데이트합니다.

  1. 문자열 배열을 입력으로 받습니다.
  2. 각 문자열의 길이를 length로 비교하여 가장 긴 문자열을 찾습니다.
  3. 조건문을 사용하여 현재 최대 길이를 초과할 때만 최대 길이와 해당 문자열을 갱신합니다.
function findLongestString(s) {
  let max = Number.MIN_VALUE;  // 초기화: 가장 작은 값으로 시작
  let answer = '';

  // 각 문자열의 길이를 확인하여 가장 긴 문자열 찾기
  for (let x of s) {
    if (x.length > max) {
      max = x.length;  // 최대 길이 갱신
      answer = x;      // 최대 길이의 문자열 저장
    }
  }

  return answer;
}

// 예제 실행
const strings = ["teacher", "time", "student", "beautiful", "good"];
console.log(findLongestString(strings));  // 출력: beautiful

15. 기본 문제 / 가운데 문자 출력(substring, substr)

이 문제는 문자열의 길이를 확인하여 가운데 문자를 출력하는 문제입니다. 주어진 문자열의 길이가 홀수인 경우에는 가운데 문자 한 개를 출력하고, 짝수인 경우에는 가운데 두 문자를 출력합니다. 이를 위해 Math.floor, substring, substr 등의 메서드를 활용하여 가운데 위치에 따라 분기 처리합니다.

  1. 문자열의 길이를 length로 확인하여 홀수인지 짝수인지 판별합니다.
  2. 홀수일 경우에는 가운데 문자를, 짝수일 경우에는 가운데 두 문자를 추출합니다.
  3. 문자열 자르기를 위해 substring과 substr 메서드를 활용할 수 있습니다.
function getMiddleCharacter(s) {
  const mid = Math.floor(s.length / 2);  // 가운데 인덱스 계산
  let answer = '';

  if (s.length % 2 === 1) {
    // 홀수일 경우 가운데 한 글자 추출
    answer = s.substring(mid, mid + 1);
  } else {
    // 짝수일 경우 가운데 두 글자 추출
    answer = s.substring(mid - 1, mid + 1);
  }

  return answer;
}

// 예제 실행
console.log(getMiddleCharacter("study"));    // 출력: "u"
console.log(getMiddleCharacter("good"));     // 출력: "oo"
console.log(getMiddleCharacter("teacher"));  // 출력: "c"
console.log(getMiddleCharacter("length"));   // 출력: "ng"

16. 기본 문제 / 중복문자제거(indexOf)

이 문제는 문자열 내 중복 문자를 제거하고, 유일한 문자를 원래 입력 순서대로 출력하는 문제입니다. JavaScript의 indexOf 메서드를 활용하여 문자열에서 처음 나타나는 문자를 확인하고, 이미 확인된 중복 문자는 제거하여 저장하는 방식입니다.

  1. 문자열의 각 문자를 for 문으로 순차적으로 탐색합니다.
  2. 각 문자의 indexOf 값이 해당 인덱스와 같다면 최초 등장 문자로 간주하고 결과 문자열에 추가합니다.
  3. 특정 문자의 개수는 indexOf의 두 번째 인자를 사용하여 중복 문자의 등장 횟수를 세는 방식으로 구할 수 있습니다.
function removeDuplicates(s) {
  let answer = '';

  for (let i = 0; i < s.length; i++) {
    // 문자 첫 등장 여부 확인
    if (s.indexOf(s[i]) === i) {
      answer += s[i];
    }
  }

  return answer;
}

// 특정 문자의 개수를 세는 추가 기능
function countCharacter(s, char) {
  let count = 0;
  let pos = s.indexOf(char);

  // 문자열 내에서 특정 문자의 개수 세기
  while (pos !== -1) {
    count++;
    pos = s.indexOf(char, pos + 1);
  }

  return count;
}

// 예제 실행
console.log(removeDuplicates("ksekkset"));  // 출력: "kset"
console.log(countCharacter("ksekkset", "k")); // 출력: 3

17. 기본 문제 / 중복단어제거

이 문제는 중복 단어를 제거하고 원래 입력된 순서를 유지한 채로 결과를 출력하는 문제입니다. filter와 indexOf 메서드를 활용하여 첫 번째로 등장하는 단어만 남기고, 중복되는 단어는 제거하는 방식으로 해결합니다.

  1. filter 메서드를 사용하여 배열을 탐색하고 중복된 단어를 제거합니다.
  2. indexOf 메서드를 사용해 각 단어가 처음 등장하는 인덱스를 확인합니다.
  3. 단어가 첫 번째로 등장하는 위치와 현재 탐색 중인 인덱스가 같으면 배열에 포함하고, 그렇지 않으면 제외하여 중복을 제거합니다.
function removeDuplicateWords(words) {
  // 중복을 제거하고 순서를 유지한 배열을 반환
  return words.filter((word, index) => words.indexOf(word) === index);
}

// 예제 실행
console.log(removeDuplicateWords(["good", "time", "good", "time", "student"]));  
// 출력: ["good", "time", "student"]

1. 1, 2차원 배열 탐색 / 큰 수 출력하기