[162. Find Peak Element] (알고리즘)
Binary Search
문제
A peak element is an element that is strictly greater than its neighbors.
Given a 0-indexed integer array nums
, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.
You may imagine that nums[-1] = nums[n] = -∞
. In other words, an element is always considered to be strictly greater than a neighbor that is outside the array.
You must write an algorithm that runs in O(log n)
time.
Example 1:
Input: nums = [1,2,3,1] Output: 2 Explanation: 3 is a peak element and your function should return the index number 2.
Example 2:
Input: nums = [1,2,1,3,5,6,4] Output: 5 Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6.
Constraints:
1 <= nums.length <= 1000
-231 <= nums[i] <= 231 - 1
nums[i] != nums[i + 1]
for all validi
.
스스로 고민
접근법
- 가장 큰 숫자의 인덱스를 반환해주면 된다.
- 피크는 여러 개가 있을 수 있지만 그냥 한 개만 반환하면 된다.
의사코드
- 오름차순으로 정렬을 해준다.
- 가장 마지막 숫자의 인덱스를 찾아서 반환해준다.
구현 코드
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
sorted_nums = sorted(nums)
x = sorted_nums[-1]
y = nums.index(x)
return y
시간 복잡도와 공간 복잡도
-
시간복잡도: 주어진 코드의 시간복잡도는 O(n log n) 다. 이유는 코드에서
sorted(nums)
를 사용하여 배열을 정렬하기 때문이다. 정렬 알고리즘의 시간복잡도가 일반적으로 O(n log n)이기 때문에 코드 전체의 시간복잡도도 O(n log n) 다. -
공간복잡도: 주어진 코드의 공간복잡도는 O(n) 다. 이유는
sorted_nums
라는 새로운 배열을 생성하여 입력 배열nums
를 복사하고 정렬한 후 사용하기 때문이다. 따라서 추가적인 메모리 공간이 입력 배열과 정렬된 배열 두 개를 모두 사용한다.
회고 과정
테스트는 통과했지만 이진 검색이 아니라서 이진 검색으로 다시 만들어봤다.
지금 코드에서 뭘 개선할 수 있지?
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = left + (right - left) // 2 # 중간 인덱스 계산
if nums[mid] > nums[mid + 1]:
# 현재 중간 요소가 다음 요소보다 크다면 왼쪽 반쪽을 살펴봅니다.
right = mid
else:
# 현재 중간 요소가 다음 요소보다 작다면 오른쪽 반쪽을 살펴봅니다.
left = mid + 1
# left와 right가 만나는 지점이 피크의 위치입니다.
return left
다른 사람 코드를 보고 그 기준으로 어떤 부분을 개선 할 수 있는지 최종 회고
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
# if curr mid is less than one of surrounding, we know it is
# not a peak
# l = 0
# r = len(nums) - 1
# while l <= r:
# mid = l + (r - l) // 2
# if nums[mid] >= nums[mid + 1] and nums[mid] >= nums[mid - 1]:
# return mid
# elif nums[mid] >= nums[l]:
# l = mid + 1
# else:
# r = mid - 1
# return -1
return nums.index(max(nums))
- 파이썬 함수만 잘 알고 있다면 정말 쉽게 풀 수 있는 예
댓글남기기