-
[LeetCode] Array101 - Third Maximum NumberAlgorithm 2021. 5. 23. 15:09
Third Maximum Number
Given integer array nums, return the third maximum number in this array. If the third maximum does not exist, return the maximum number.
Example 1:
Input: nums = [3,2,1] Output: 1 Explanation: The third maximum is 1. Example 2:
Example 2:
Input: nums = [1,2] Output: 2 Explanation: The third maximum does not exist, so the maximum (2) is returned instead. Example 3:
Example 3:
Input: nums = [2,2,3,1] Output: 1 Explanation: Note that the third maximum here means the third maximum distinct number. Both numbers with value 2 are both considered as second maximum.
Constraints:
- 1 <= nums.length <= 104
- -231 <= nums[i] <= 231 - 1
Follow up: Can you find an O(n) solution?
이제 2문제만 더 풀면 Array101 시리즈가 끝이 난다.. 🎉
일단 이번주에 푼 문제 중에 제일 재밌었던 문제를 적어보려고 한다.
주어진 배열 중에서 3번째로 큰 숫자를 찾아내고, 만약 3번째로 큰 숫자가 없다면 첫 번째로 큰 숫자를 리턴하는 문제이다.
중요한 점은 중복 숫자는 제외해야한다.
sort나 filter 메소드를 사용하면 금방 풀겠지만 중요한건 시간 복잡도가 O(n)이어야한다는 점이다.
일단 filter와 Math.max 메소드를 사용해서 푼 방법은 다음과 같다.
/** * @param {number[]} nums * @return {number} */ var thirdMax = function(nums) { let filtered = nums; let max = Math.max(...nums); const result = [max]; for (let i = 0; i < 2; i++) { filtered = filtered.filter(num => num !== max); if (filtered.length === 0) return result[0]; max = Math.max(...filtered); result.push(max); } return max; };
제일 큰 숫자를 찾아내고, 해당 숫자를 배열에서 전부 제거한다.
이걸 3번 반복하면 3번째로 큰 숫자가 나온다.
만약 3번째로 큰 숫자가 없다면 제일 큰 숫자를 리턴한다.
이 방법의 문제점은 filter를 반복하면서 계속 loop을 돈다는 것이다.
딱 한 번만 loop을 돌면서 세번째로 큰 숫자를 찾아내야하기 때문에 다른 방법을 고민해보았다.
/** * @param {number[]} nums * @return {number} */ var thirdMax = function(nums) { let first = nums[0]; let second = null; let third = null; for (let i = 1; i < nums.length; i++) { if (nums[i] > first) { third = second; second = first; first = nums[i]; } else if (second === null || nums[i] > second) { if (nums[i] !== first) { third = second; second = nums[i]; } } else if (third === null || nums[i] > third) { if (nums[i] !== second) { third = nums[i]; } } } return third === null ? first : third; };
그게 바로 이 방법인데,
변수를 3개 만들어서 숫자가 큰 순서대로 담는 방법이다.
근데 아무래도 if문 조건이 복잡해서 조금 코드가 지저분하게 보이는데,
LeetCode에 답을 submit하고 다른 사람이 푼 코드를 둘러보다가 아주 획기적인 방법을 발견했다.
/** * @param {number[]} nums * @return {number} */ var thirdMax = function(nums) { let first = nums[0]; let second = -Infinity; let third = -Infinity; for (let i = 1; i < nums.length; i++) { if (nums[i] > first) { third = second; second = first; first = nums[i]; } else if (nums[i] < first && nums[i] > second) { third = second; second = nums[i]; } else if (nums[i] < second && nums[i] > third) { third = nums[i]; } } return third === -Infinity ? first : third; };
위에 내가 푼 방법과 거의 유사하지만,
second와 third의 초기값을 -Infinity로 한다는 점이 넘나 굿 아이디어! 👍
Infinity는 다른 어떤 수보다 크기 때문에 -Infinity는 다른 어떤 수보다 작다는 것을 활용해서 푼 방법이다.
반응형'Algorithm' 카테고리의 다른 글
[LeetCode] Array101 - Find All Numbers Disappeared in an Array (252) 2021.05.29 [LeetCode] Arrays101 - Valid Mountain Array (251) 2021.05.16 [LeetCode] Arrays101 - Remove Duplicates from Sorted Array (252) 2021.05.09 [LeetCode] Arrays101 - Remove Element (127) 2021.05.09 [LeetCode] Arrays101 - Merge Sorted Array (252) 2021.05.08 COMMENT