
안녕하세요 :)
오늘은 5월 2주차 4번째 알고리즘인 Maximum Points You Can Obtain from Cards 풀이를 적어보겠습니다.

요약
주어진 cardPoints 배열에서 가장 처음 요소 또는 가장 마지막 요소를 포함하고, 연속된 위치에 있는 k 개의 수들 중 가장 큰 값을 찾아 return 하는 문제입니다.
이제 Leet Code를 몇 번 풀었다고 무작정 for문을 순회하는 코드는 생각하지 않았습니다. (장족의 발전)
처음에는 무조건 처음 또는 끝에서만 시작하는 연속된 수라고 생각해서 왼쪽부터 요소들을 누적해서 저장하는 배열과 오른쪽부터 요소들을 누적해서 저장하는 배열 두 개를 만들어서
k요소와length-k요소 중에max를 return하도록 했습니다.
음.. 그런데 문제를 잘못 이해한 것을 Submit 버튼을 눌러보고 알았습니다.
잘못 도출되는 답이 있더라고요.
힌트는 아직 볼 단계가 아니라고 생각해서, 또 생각을 해봤습니다.
Time Limit를 마주치지 않기 위해서, 우선 처음과 끝으로부터의
k번째 인덱스까지 누적 합을 구한 배열은 그대로 두었습니다.
그리고max를 구하는 방법을 바꾸었습니다.
그랬더니 Accept를 받았습니다!
너무 기뻤고,, 네,, 힌트를 보지 않고 푼 최초의 문제가 되었습니다.
이제부터 그 방법을 설명하겠습니다.
int max = 0;
int[] leftSumArr = new int[k + 1];
int[] rightSumArr = new int[k + 1];
leftSumArr[1] = cardPoints[0];
rightSumArr[1] = cardPoints[cardPoints.length - 1];
최대값을 비교할 max 변수와 왼쪽부터 누적 합을 저장하는 leftSumArr , 오른쪽부터 누적 합을 저장하는 rightSumArr 를 선언해주었습니다.
그리고 누적 합의 배열의 길이는 k+1 로 설정하고, 1부터 누적 합을 저장했습니다.
그래서, 1번 인덱스에는 cardPoints 의 처음과 끝 값이 저장됩니다.
for (int i = 1; i <= k; i++) {
leftSumArr[i] = leftSumArr[i - 1] + cardPoints[i - 1];
rightSumArr[i] = rightSumArr[i - 1] + cardPoints[cardPoints.length - i];
}
계속 언급했던 것처럼 누적 합이므로, 구할 인덱스의 이전 인덱스와 cardPoints 값을 더해주면 됩니다.
cardPoints가 [1, 2, 3, 4, 5, 1] 이고k가 3이라면,
leftSumArr는 [0, 1, 3, 6]이 되고
rightSumArr는 [0, 1, 6, 10]이 됩니다.
이 다음에서, max 값을 구하는 방법이 나옵니다.
for (int i = 0; i <= k; i++) {
max = Math.max(max, leftSumArr[i] + rightSumArr[k - i]);
}
leftSumArr 와 rightSumArr 의 값을 더해서 비교해줍니다.
위의 예시와 이어서 생각하면,
0+10vs1+6vs3+1vs6+0
이 되는 것입니다.
이렇게 max 값을 구하면, 모든 경우를 생각하면서도 깔끔한 코드로 구할 수 있습니다!
class Solution {
public int maxScore(int[] cardPoints, int k) {
int max = 0;
int[] leftSumArr = new int[k + 1];
int[] rightSumArr = new int[k + 1];
leftSumArr[1] = cardPoints[0];
rightSumArr[1] = cardPoints[cardPoints.length - 1];
for (int i = 1; i <= k; i++) {
leftSumArr[i] = leftSumArr[i - 1] + cardPoints[i - 1];
rightSumArr[i] = rightSumArr[i - 1] + cardPoints[cardPoints.length - i];
}
for (int i = 0; i <= k; i++) {
max = Math.max(max, leftSumArr[i] + rightSumArr[k - i]);
}
return max;
}
}
이번 문제는 조금 쉬운 문제였던 것 같습니다.
그래도 힌트를 보지 않고 푼 문제여서 엄청 뿌듯하네요 !!
이번 포스팅도 읽어주셔서 감사합니다 :)