주어진 숫자 배열 안에 연속된 부분 배열 중 가장 큰 값을 리턴하면 되는 심플 한 문제이다. 문제만 심플하지 생각할 것이 꽤 많은 문제였다.
문제풀이를 하면서 다양하게 접근했다. 저기 주어진 예시들 은 길고 특별한 케이스이니 심플하게 만들어서 생각해보자.
[-3,2,3,-1]
뭐 있나 1번 부터 다 쓰자...
1번 인덱스 : 뭐 할 게 없다 그냥 리턴해줘야 한다...-3
2번 인덱스 : [-3], [2] / [-3,2] 오 뭔가 느낌이 온다.
3번 인덱스 : [-3], [2], [3] / [-3,2], [2,3] / [-3,2,3] 왔다, 약간 dp 스럽게 풀어야 하는 건가 싶었다.
현재 인덱스까지 진행된 것 중 버릴 거 버리면서 진행한다면 나쁘지 않은 효율이 나올 것 같았다.
뭘 어떻게 버려 주어야 할까 고민하다가, 현재 진행 중인 값에 다음 값을 더해서 그 값이 다음값 보다 작다면? 뒤에 까지 다 더한 것은 쓸모가 없어진다.. -2 1 -3을 예로 들어보자 -2 1 => -1 인 상태에서 -3 을 더하면? -4인데 우리는 연속된 수를 구해야 하니 버리자 대신 저 앞에 까지 더해진 부분을 따로 기록을 해 두어야 할 것이다.
class Solution {
public int maxSubArray(int[] arr) {
if(arr.length == 1) return arr[0];
int p1 = 0;
int p2 = 1;
int maxSum = arr[p1];
int currentSum = arr[p1];
while(p2<arr.length){
int nextCur = currentSum + arr[p2];
if(nextCur < arr[p2]){
p1 = p2;
currentSum = arr[p2];
}else{
currentSum = nextCur;
}
maxSum = Math.max(maxSum,currentSum);
p2++;
}
return maxSum;
}
}
오늘 two pointer 강의를 듣고 와서 그런가 엄청 비슷하게 푼 거 같은데 허점이 존재한다.... p1을 선언해 놓고 쓰지도 않는다......
고수들의 코드를 보자.
class Solution {
public int maxSubArray(int[] nums) {
int currSum = nums[0], result = nums[0];
for (int i=1;i<nums.length;i++){
currSum = Math.max(nums[i], currSum + nums[i]);
result = Math.max(result, currSum);
}
return result;
}
}
호 올리 몰리...... math.max를 이렇게 선언하면서 깔끔하게 for 반복문으로 해결해 버리는 아름다운 코드이다. 조금 더 디스커스를 둘러보면 Kadane's Algorithm 이란 글로 엄청 아름답게 써놓은 글이 있다. 따로 퍼오기 좀 그러니 링크를 첨부하겠다.
개괄적으로 설명을 하자면 위의 풀이법 그대로가 카 데인 알고리즘이다. 글 설명 10줄보다 그림 이 훨씬 보기 편하니 아래 링크로 이동해서 확인하면 더 도움 이 됩니다.
보러 가기
이 사람이 작성한 글에 의하면 어느 부분이던 합이 - 에 도달한다면, 이걸 계속 가지고 있을 의미가 없기 때문에 합을 0으로 초기화시켜준다고 한다.
-2 1 -3 4 -1 2 1 -5 4 (예시 1번)
i = 0 일 때 합은 -2 가 되고 , 최대 합은 -2 , 합이 0 보다 작기 때문에 현재 합은 0으로 초기화된다.
i = 1 일 때 합은 0+1(현재 합을 0 으로 초기화 시켜서 전 인덱스에서) 이되고, 합이 1 이된다 최대합은 1
i = 2 일 때 합은 1 -3 -2 가 되고 최대합은 1, 현재합은 0으로 초기화된다 왜 ? 0보다 작아서
i = 3 일때 합은 0+4 4 가되고 최대합은 4, 현재합은 4 가된다
이런 식으로 쭉쭉 이어나가면 된다. 위 링크에 더 자세히 설명되어 있으니 참고 바랍니다.!!
자세히 다시 보니 브루트 포스 에서 내가 느낀 그 디피 느낌이 이 카데인 알고리즘 이였다 그냥 디피라고 하면 될걸 왜 굳이 이름을 이렇게 붙이는지 다시보니 도둑이 집터는 문제랑 매우 유사하다고 생각된다...... 현재 합과, 현재 인덱스 중 큰 것, 또 맥스 값과 큰 것을 비교하는 법
왜 항상 모든 블로그 혹은 유튜브 비디오에서 항상 브루트 포스를 먼저 하라고 하는지 다시 한번 느끼는 문제였다..
'PS > LeetcCode' 카테고리의 다른 글
33. Search in Rotated Sorted Array (0) | 2022.07.04 |
---|---|
34. Find First and Last Position of Element in Sorted Array (0) | 2022.07.03 |
242. Valid Anagram (0) | 2022.06.26 |
383. Ransom Note (0) | 2022.06.26 |
387. First Unique Character in a String (0) | 2022.06.26 |