프라이D
프라이Develog(❁´◡`❁)
프라이D
전체 방문자
오늘
어제
  • ALL (378)
    • TDD, Cleancode with JavaScr.. (5)
    • 프로젝트 (32)
      • work (3)
      • 직접 만드는 기술 블로그 (2)
      • 데일리 옥션 (19)
      • 모락모락 (8)
    • Computer Science (1)
    • Algorithm & 자료구조 (94)
      • 알고리즘 w.JavaScript (53)
      • 자료구조 (5)
      • (인프런) 자바스크립트 알고리즘 문제풀이 (34)
    • JavaScript (45)
      • JavaScript (41)
      • 모던 자바스크립트 Deep Dive (4)
    • WEB (13)
    • 회고 (12)
    • TIL (109)
    • WIL (7)
    • Stacks (20)
      • React.js (6)
      • Next.js (1)
      • Redux (3)
      • Node.js (2)
      • GIT (2)
      • SAP (1)
    • 15일 메이킹 프로젝트 (15)
    • 이전 기록 (14)
    • ETC. (5)
    • ---------------2021 (6)
      • 내일배움단-웹개발 5주 (2)
      • 정보처리기사 (4)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • 비트마스크
  • 자바스크립트비트마스크
  • 내일배움카드
  • 모던자바스크립트딥다이브
  • 알고리즘
  • 코드스테이츠
  • MySQL
  • 투포인터알고리즘
  • 내일배움단
  • 국비지원
  • vanilaJS
  • 2023 인프콘 후기
  • 자바스크립트
  • 코딩프로젝트
  • Til
  • 자바스크립트알고리즘
  • nomadcoder
  • 스파르타코딩클럽
  • nomadcoders
  • JavaScript

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
프라이D

프라이Develog(❁´◡`❁)

Algorithm & 자료구조/(인프런) 자바스크립트 알고리즘 문제풀이

[알고리즘] 연속 부분수열 2 (투포인터 알고리즘)

2022. 9. 9. 14:21

문제

N개의 수로 이루어진 수열이 주어집니다.

이 수열에서 연속 부분수열의 합이 특정 숫자 M 이하가 되는 경우가 몇 번 있는지 구하는 프로그램을 작성하세요. 

풀이

const M = 5;
const arr = [1, 3, 1, 2, 3];

function solution1(M, arr) {
  const N = arr.length;
  let lt = 0;
  let count = 0;
  let sum = 0;

  for (let rt = 0; rt < N; rt++) {
    // 현재까지 부분집합의 합계를 구하기 위해 sum에 rt 값을 더한다.
    sum += arr[rt];
    // 만약 sum이 M을 초과한다면, lt만큼 빼주고 lt를 앞으로 이동시킨다.
    while (sum > M) sum -= arr[lt++];
    // 이 과정이 끝나고 sum이 M 이하인 경우, 현재 lt부터 rt 값 까지의 부분집합 갯수를 구해 더해준다.
    count += rt - lt + 1;
  }
  return count;
}

const resultl = solution1(M, arr);
console.log(resultl);

현재 원소 까지의 부분집합의 합을 구하기 위해 lt와 rt라는 두 개의 포인터를 사용하는 투포인터 알고리즘 문제이다. 

  • lt와 rt 두 개의 포인터를 0으로 초기화 시킨 후, sum이 M을 초과할 때 까지 계속해서 더한다.
  • 어느 순간 sum이 M을 초과하는 순간이 오는데, 이 때는 lt를 움직여서 sum에서 lt 가 가리키는 값을 빼 주면 새로운 부분집합이 된다.
  • M 이하인 부분집합의 갯수이기 때문에 arr의 각 원소도 부분집합에 포함이 된다. 현재 rt 가 가리키는 원소값을 더했을 때 sum 이 M 이하라면, rt가 가리키는 원소를 포함해 그 이전의 모든 원소를 포함한 부분집합이 여러개 생기는 것이다.
  • 따라서 sum 이 M 이하라면 부분집합이 생길 것이고 이 부분집합의 갯수를 rt - lt + 1 로 구해줄 수 있다. sum이 M을 초과하면 lt도 증가되며 빠질 것이기 때문에 각 단계에서 중복되지 않는 부분집합의 갯수를 구할 수 있다. 

코드를 따라가며 각 단계에서 결과값이 도출되는 과정을 설명하면 아래와 같다. 

/*
[풀이과정]

arr = [1,3,1,2,3] 일 때 코드의 풀이 과정.

1. sum = 0, count = 0, lt = 0, rt = 0
- sum에 arr[0]인 1이 더해진다.
- 1 은 M(5)보다 작으므로, count에는 0 - 0 + 1 => 1이 더해진다.(부분집합은 [1])

2. sum = 1, count = 1, lt = 0, rt = 1
- sum에 arr[1] 인 3이 더해진다. 
- 4는 5보다 작으므로, count에는 1 - 0 + 1 => 2가 더해진다. (부분집합은 [1, 3], [3] => 2개)

3. sum = 4, count = 3, lt = 0, rt = 2
- sum 에 arr[2]인 1이 더해진다.
- 5는 5와 같으므로 count에는 2 - 0 + 1 => 3이 더해진다. (부분집합은 [1, 3, 1], [3, 1], [1] => 3개)

4. sum = 5, count = 6, lt = 0, rt = 3
-sum += arr[3] => 7
- 7은 5보다 크므로, while문으로 진입해 lt를 증가시키며 sum에서 빼준다.
- 최종적으로 lt = 2, sum = 3, rt = 3
- 3 - 2 + 1 은 2 이다. (부분집합은 [1, 2], [2] => 2개)

5. sum = 3, count = 8, lt = 2, rt = 4
- sum += arr[4] = 6
- while문으로 진입하여 lt = 3, sum = 5
- 4 - 3 + 1 = 2 부분집합은 [2,3], [3] => 2개이다.

최종적으로 카운트는 1 + 2 + 3 + 2 + 2 => 10개이다. 


*/

 

저작자표시 (새창열림)

'Algorithm & 자료구조 > (인프런) 자바스크립트 알고리즘 문제풀이' 카테고리의 다른 글

[알고리즘] 모든 아나그램 찾기  (0) 2022.09.18
[알고리즘] 최대매출  (0) 2022.09.09
[알고리즘] 모든 아나그램 찾기(해쉬, 투포인터, 슬라이딩 윈도우)  (0) 2022.04.20
[알고리즘] 순열구하기  (0) 2022.03.19
[알고리즘] 중복순열 구하기  (0) 2022.03.16
    'Algorithm & 자료구조/(인프런) 자바스크립트 알고리즘 문제풀이' 카테고리의 다른 글
    • [알고리즘] 모든 아나그램 찾기
    • [알고리즘] 최대매출
    • [알고리즘] 모든 아나그램 찾기(해쉬, 투포인터, 슬라이딩 윈도우)
    • [알고리즘] 순열구하기
    프라이D
    프라이D
    틀린내용 정정 및 개선사항은 언제든지 댓글 달아주세요 :D

    티스토리툴바