티스토리 뷰
[LeetCode - Daily Challenge] 153. Find Minimum in Rotated Sorted Array
Jaime.Lee 2021. 9. 1. 10:40Problem
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums
= [0,1,2,4,5,6,7] might become:
[4,5,6,7,0,1,2] if it was rotated 4 times.
[0,1,2,4,5,6,7] if it was rotated 7 times.
Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2],
..., a[n-2]].
Given the sorted rotated array nums of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time.
Example 1:
Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.
Example 2:
Input: nums = [4,5,6,7,0,1,2]
Output: 0
Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Example 3:
Input: nums = [11,13,15,17]
Output: 11
Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
Constraints:
- n == nums.length
- 1 <= n <= 5000
- -5000 <= nums[i] <= 5000
- All the integers of nums are unique.
- nums is sorted and rotated between 1 and n times.
Solution
오름차순을 오른쪽으로 회전시킨 배열이 주어질 때 이 배열의 원소중 최솟값을 구하는 문제입니다.
시간 복잡도 O(log n) 안에 최솟값을 찾아야하기 때문에 순차적으로 탐색하면서 가장 낮은 값을 찾는 방식을 사용하면 O(n)이 되어 문제를 통과하지 못하겠죠?
두 개의 포인터를 사용해 왼쪽 포인터의 값이 오른쪽 포인터의 값보다 작아지는 순간에 왼쪽 포인터의 값을 반환하면 간단히 답을 찾을 수 있습니다.
[6, 7, (1), 2, 3, 4, 5]
^ ^
이 때 매 번 중간값을 다시 계산해야 O(log n) 안에 수행될 수 있고, 각 포인터를 움직이는 조건은 중간값과 비교하여 결정합니다.
왼쪽 포인터의 값이 중간값보다 큰 경우 최솟값은 그 사이에 위치하게 되므로 오른쪽 포인터의 위치를 중간값의 위치로 바꿔줍니다.
[7, (1), 2, 3, 4, 5, 6]
^ ^ <----- ^
반대로 왼쪽 포인터의 값이 중간값보다 작거나 같은 경우 최솟값은 중간값과 오른쪽 포인터 사이에 위치하게 되므로 왼쪽 포인터의 위치를 중간값의 다음 위치로 바꿔줍니다.
[4, 5, 6, 7, (1), 2, 3]
^ ^ ^
-----------> ^
여기서 왼쪽 포인터가 최솟값일 경우는 앞에 조건에서 걸러지기 때문에 생각할 필요가 없습니다.
이 내용을 구현하면 아래와 같습니다.
public class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
if (nums[left] <= nums[right]) {
return nums[left];
}
int m = (left + right) / 2;
if (nums[m] >= nums[left]) {
left = m + 1;
} else {
right = m;
}
}
return -1;
}
}
Test
package io.lcalmsky.leetcode.find_minimum_in_rotated_sorted_array;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SolutionTest {
@Test
public void givenArray_whenFindMinimum_thenCorrect() {
assertAll(
() -> test(new int[]{3, 4, 5, 1, 2}, 1),
() -> test(new int[]{4, 5, 6, 7, 0, 1, 2}, 0),
() -> test(new int[]{3, 1, 2}, 1)
);
}
private void test(int[] given, int expected) {
// when
Solution solution = new Solution();
int actual = solution.findMin(given);
// then
assertEquals(expected, actual);
}
}
'Algorithm > LeetCode' 카테고리의 다른 글
[LeetCode] 96. Unique Binary Search Trees (Java) (0) | 2021.09.03 |
---|---|
[LeetCode - Daily Challenge] 565. Array Nesting (0) | 2021.09.02 |
[LeetCode - Daily Challenge] 598. Range Addition II (0) | 2021.08.31 |
[LeetCode - Daily Challenge] 330. Patching Array (0) | 2021.08.30 |
[LeetCode - Daily Challenge] 331. Verify Preorder Serialization of a Binary Tree (0) | 2021.08.27 |
- Total
- Today
- Yesterday
- spring boot jwt
- 함께 자라기
- JPA
- 스프링 부트 튜토리얼
- 헥사고날 아키텍처
- Java
- Jackson
- leetcode
- Spring Boot
- 스프링 데이터 jpa
- proto3
- 함께 자라기 후기
- @ManyToOne
- 클린 아키텍처
- 스프링 부트 애플리케이션
- gRPC
- Spring Boot Tutorial
- 알고리즘
- 스프링 부트 회원 가입
- Spring Data JPA
- spring boot application
- Linux
- intellij
- spring boot app
- QueryDSL
- Spring Boot JPA
- JSON
- 스프링부트
- 스프링 부트
- r
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |