Algorithm - Programmers Problems (week 12)

이소라·2023년 6월 6일
0

Algorithm

목록 보기
48/77
post-custom-banner

Problem (lev.2) : 연속된 부분 수열의 합

  • 비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.

    • 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다.
    • 부분 수열의 합은 k입니다.
    • 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다.
    • 길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다.
  • 수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요.

    • 이때 수열의 인덱스는 0부터 시작합니다.

제한사항

  • 5 ≤ sequence의 길이 ≤ 1,000,000
  • 1 ≤ sequence의 원소 ≤ 1,000
  • sequence는 비내림차순으로 정렬되어 있습니다.
  • 5 ≤ k ≤ 1,000,000,000
  • k는 항상 sequence의 부분 수열로 만들 수 있는 값입니다.

Solution

  • two pointer를 사용하여 모든 부분 수열의 처음과 마지막 인덱스를 저장한 뒤 정렬해서 가장 길이가 짧은 앞쪽 수열의 처음과 마지막 인텍스를 반환함
function solution(sequence, k) {
    const answer = [];
    let left = 0;
    let right = 0;
    let sum = sequence[0];
    
    while (right < sequence.length) {
        if (sum < k) {
            right++;
            sum += sequence[right];
        } else if (sum > k) {
            sum -= sequence[left];
            left++;
        } else {
            answer.push([left, right]);
            right++;
            sum += sequence[right];
        }
    }
    
    const compare = (a, b) => {
        const sequenceLengthDiff = (a[1] - a[0]) - (b[1] - b[0]);
        return sequenceLengthDiff || a[0] - b[0];
    }
    
    return answer.sort(compare)[0];
}



Problem (lev.1) : 문자열 나누기

  • 문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.
    • 먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
    • 이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
    • s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
    • 만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.
  • 문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.

제한사항

  • 1 ≤ s의 길이 ≤ 10,000
  • s는 영어 소문자로만 이루어져 있습니다.

입출력 예

  • 예시 1

    • 입력 : s = "banana"
    • 출력 : 3
    • 설명 : s = "banana"인 경우 ba - na - na와 같이 분해됩니다.
  • 예시 2

    • 입력 : s = "abracadabra"
    • 출력 : 6
    • 설명 : s = "abracadabra"인 경우 ab - ra - ca - da - br - a와 같이 분해됩니다.
  • 예시 3

    • 입력 : s = "aaabbaccccabba"
    • 출력 : 3
    • 설명 : s = "aaabbaccccabba"인 경우 aaabbacc - ccab - ba와 같이 분해됩니다.

Solution

function solution(s) {
    let answer = 0;
    
    const divideStr = (startIndex, endIndex) => {
        let prevStr = s[startIndex];
        let prevStrCount = 1;
        let otherStrCount = 0;
        
        if (startIndex > s.length) {
            return;
        }
        
        for (let index = startIndex + 1; index <= endIndex; index++) {
            const str = s[index];
            if (str === prevStr) {
                prevStrCount++;
            } else {
                otherStrCount++;
            }
            if (prevStrCount === otherStrCount) {
                answer++;
                return divideStr(index + 1, endIndex);
            }
        }
        if (startIndex <= endIndex) {
            answer++;
        }
    }
    
    divideStr(0, s.length - 1);
    return answer;
}
post-custom-banner

0개의 댓글