문제
N개의 수로 이루어진 수열이 주어집니다. 이 수열에서 연속부분수열의 합이 특정숫자 M이 되는 경우가 몇 번 있는지 구하는 프로그램을 작성하세요.
만약 N=8, M=6이고 수열이 다음과 같다면
1 2 1 3 1 1 1 2
합이 6이 되는 연속부분수열은 {2, 1, 3}, {1, 3, 1, 1}, {3, 1, 1, 1}로 총 3가지입니다.
입력예제
N=8, M=6
1 2 1 3 1 1 1 2
강사님의 풀이
function solution(m, arr){
let answer = 0;
let sum = 0;
let left = 0;
//left, right 두개의 포인터로 시작, right는 for문 안에서 증감된다.
for(let right = 0; right<arr.length; right++){
sum+=arr[right]; //sum에 arr[right]값을 누적한다
if(sum===m)answer++; //누적된 sum 값이 m과 일치하는지 확인
while(sum>=m){ //sum이 m보다 크거나 같으면, 작아질 때 까지 arr[left]값을 뺀다.
sum-=arr[left++]; //sum에 arr[left]뺀 값을 누적시키고, ++ 후위 연산한다.
if(sum===m) answer++ //sum이 m 과 같은지 확인
}
}
return answer;
}
let a=[1, 2, 1, 3, 1, 1, 1, 2];
console.log(solution(6, a));
- left와 right 두 개의 포인터가 돌며, right 값을 sum에 누적시킨다.
- 만약 누적시킨 값이 m보다 크거나 같다면, 증감되지 않은 left값을 빼면서 증감시킨다.
- 누적된 sum 값이 m보다 작다면 while문을 빠져나와 다시 right 값을 증감시키며 sum을 누적시킨다.
- 두 가지 경우 모두 sum이 m과 같은지 확인해 같다면 answer를 누적시킨다.
나의 풀이
function solution(m, arr){
let answer=0;
let p1 = 0;
let p2 = 0;
let sum = 0;
while(p2<arr.length){ //p2포인터가 length 범위를 빠져나가면 반복이 끝난것으로 간주
if(sum<m) sum+=arr[p2++]; //sum이 m보다 작은 경우 sum에 arr[p2]를 누적시키고 ++
if(sum>m) sum-=arr[p1++] //sum이 m보다 큰 경우 sum에서 arr[p1]을 빼고 ++
if(sum===m){ //sum이 m과 같다면 answer누적
answer++;
sum-=arr[p1++]; //left값이 움직여 sum이 작아질 수 있도록 arr[p1]을 빼고 ++
}
}
return answer;
}
let a=[1, 2, 1, 3, 1, 1, 1, 2];
console.log(solution(6, a));
'Algorithm & 자료구조 > (인프런) 자바스크립트 알고리즘 문제풀이' 카테고리의 다른 글
[알고리즘] 학급회장 (해쉬) (0) | 2022.02.22 |
---|---|
[알고리즘] 부분 수열의 합 2 (0) | 2022.02.17 |
[알고리즘] 공통원소 구하기 - 투포인터 알고리즘 (0) | 2022.02.08 |
[알고리즘]k번째 큰 수 (0) | 2022.02.06 |
[알고리즘]졸업선물 - sort 정렬, 완전탐색 (0) | 2022.02.06 |