241025 과제: 코딩테스트 3문제 풀이

수달·2024년 10월 26일

코테 3문제 풀기

1. 최빈값 구하기 (Lv. 0)

https://school.programmers.co.kr/learn/courses/30/lessons/120812

최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.

  • 제한사항
    0 < array의 길이 < 100
    0 ≤ array의 원소 < 1000

  • 입출력 예
    array // result
    [1, 2, 3, 3, 3, 4] // 3
    [1, 1, 2, 2] // -1
    [1] // 1

function solution(array) {
    var answer = 0; // return 값
    let count = {}; // 객체로 숫자:카운트 수
    let maxCount = 0; // 최대 카운트 수 구하기 위해
    let mode = []; // 최빈값
    
    // 문자별로 count 저장
    for (let i = 0 ; i<array.length ; i++) {    // array 길이 동안 반복
        let m = array[i]; // 현재 문자 저장
        if (!count[m]) count[m] = 1; // count가 0일 때(없을 때) 1 삽입
        else count[m]++; // 현재 count 증가
    }  
    
    // 최빈값 찾기
    for (let num in count) {    // for..in 객체 count에서 배열의 숫자
        if (count[num] > maxCount) {    // 숫자 카운트가 max보다 클 때(반복됨)
            maxCount = count[num];  // max에 현재 숫자에 카운트 삽입
            mode = [parseInt(num)]; // 새로운 배열을 만들고(초기화), num은 문자열이기 때문에 숫자로 변환, 현재 최빈값 삽입
        } else if (count[num] === maxCount) {   // 현재 카운트와 max카운트가 같다면 (최빈값이 여러 개면)
            mode.push(parseInt(num)); // mode 배열에 최빈값을 추가
        }
    }

    // 최빈값이 하나인지 여러 개 확인
    if (mode.length > 1) {  // 여러 개일 경우
        return -1; // -1 반환
    } else {    // 1개인 경우
        return mode[0]; // 최빈값 반환 (1개이기 때문에 첫번째 배열밖에 없다)
    }
}

강의에서 06. 함수의 연습문제++ 1번 문자열 압축과 약간? 비슷할 수 있는 문제여서 풀어보았다.
연습문제++ 1번에서 count 세는 부분을 잘못 풀었었는데 잘못 푼 부분이 이 문제의 답과 비슷했다.

2. 인덱스 바꾸기 (Lv. 0)

https://school.programmers.co.kr/learn/courses/30/lessons/120895
문자열 my_string과 정수 num1, num2가 매개변수로 주어질 때, my_string에서 인덱스 num1과 인덱스 num2에 해당하는 문자를 바꾼 문자열을 return 하도록 solution 함수를 완성해보세요.

  • 제한사항
    1 < my_string의 길이 < 100
    0 ≤ num1, num2 < my_string의 길이
    my_string은 소문자로 이루어져 있습니다.
    num1 ≠ num2

  • 입출력 예
    my_string / num1 / num2 // result
    "hello" / 1 / 2 // "hlelo"
    "I love you" / 3 / 6 // "I l veoyou"

function solution(my_string, num1, num2) {
    let strArray = my_string.split('');     // 문자열을 배열로 변환
    
    // num1과 num2 위치 교환
    let temp = strArray[num1]; // 임시 변수에 num1 위치의 문자 저장
    strArray[num1] = strArray[num2]; // num1 위치에 num2 위치의 문자 할당
    strArray[num2] = temp; // num2 위치에 임시 변수의 문자 할당
    
    return strArray.join('');   // 배열을 다시 문자열로 변환
}

3. 소수 찾기 (Lv. 2)

https://school.programmers.co.kr/learn/courses/30/lessons/42839
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.

각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

  • 제한사항
    numbers는 길이 1 이상 7 이하인 문자열입니다.
    numbers는 0~9까지 숫자만으로 이루어져 있습니다.
    "013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.

  • 입출력 예
    numbers // return
    "17" // 3
    "011" // 2

풀이 방법:
1. 모든 가능한 숫자 조합 생성
2. 중복 제거
3. 소수 찾기
4. 조합 중 소수 개수 세기

function solution(numbers) {
    const singleNum = numbers.split('');    // 한 자리 숫자 배열로 나누기
    const numberList = [];  // 숫자들 저장할 배열

    // 모든 가능한 숫자 조합을 생성하는 재귀 함수
    function generateNumbers(current, others) { // 처음 시작은 current는 빈문자열, others는 한 자리 숫자들 배열
        if (current.length > 0) {   // 비어있는지 검사, 중복되지 않은 경우에만 숫자 추가
            const num = parseInt(current);  // 문자열 숫자를 정수로 변환
            if (!numberList.includes(num)) {    // 배열에 중복X 수만 삽입
                numberList.push(num);
            }
        }
        for (let i = 0; i < others.length; i++) {   // 아직 사용되지 않은 수로 조합 만들기 반복
            generateNumbers(current + others[i], others.slice(0, i) + others.slice(i + 1));  // 재귀 호출, 현재 조합 문자열에서 남은 숫자들 조합해 배열 생성: i번째 요소를 제외한 나머지 숫자들로 새 배열이 만들어짐(i번째 요소 전까지 자름 + i번째 요소 이후부터 끝까지 자름)
        }
    }

    generateNumbers('', singleNum);

    // 소수 판별 함수
    function isPrime(num) {
        if (num < 2) return false;  // 2보다 작은 수는 소수X
        for (let i = 2; i * i <= num; i++) {    // 2부터 제곱근까지 확인해 나누어 떨어지는지 검사
            if (num % i === 0) return false;    // 나누어 떨어지면 소수 X
        }
        return true;
    }

    // 소수 개수 세기
    let primeCount = 0; 
    for (const num of numberList) { // 만들어진 숫자 하나씩 검사
        if (isPrime(num)) {
            primeCount++;   // 소수라면 증가
        }
    }

    return primeCount;
}

05. 반복문 강의의 연습문제-어려움 2. 소수찾기 에서 배운 것에서 응용한 문제가 있길래 풀어보았다.
2단계가 더 높아진 느낌이다..
generateNumbers 함수 부분이 특히 이해하기 어렵다.

💫 부분 설명1

generateNumbers(current + others[i], others.slice(0, i) + others.slice(i + 1)); 
  • current + others[i]:

current: 지금까지 만든 숫자 조합을 나타냅니다.
others[i]: 아직 사용하지 않은 숫자 중 하나를 선택하는 것
-> 두 값을 더해서 current에 새로운 숫자를 추가

  • others.slice(0, i) + others.slice(i + 1):

others: 현재 선택할 수 있는 숫자들의 배열
others.slice(0, i): 배열의 i번째 요소 전까지 자른 부분
others.slice(i + 1): 배열의 i번째 요소 이후부터 끝까지 자른 부분
-> 이 두 부분을 이어 붙이면, i번째 요소를 제외한 나머지 숫자들로 새 배열이 만들어짐
이렇게 하면 현재 선택된 숫자를 제외한 나머지 숫자들이 남아서, 다음 재귀 호출에서 사용할 수 있게 됨

예시: numbers가 "013"일 때,

0개의 댓글