You are given an array of length n which was originally sorted in ascending order. It has now been rotated between 1 and n times. For example, the array nums = [1,2,3,4,5,6] might become:
[3,4,5,6,1,2] if it was rotated 4 times.
[1,2,3,4,5,6] if it was rotated 6 times.
배열의 수는 중복 x
solve : 배열 nums에서 가장 작은 수 찾기
O(log n) 풀이 필요
class Solution {
public:
int findMin(vector<int> &nums) {
int st = 0, en = nums.size()-1;
while (st < en) {
int mid = (st + en) / 2;
int st_ = nums[st], en_ = nums[en], mid_ = nums[mid];
if (st_ > mid_ && en_ > mid_) return mid_;
else if (st_ < mid_) {
if (en_ > mid_) en = mid-1;
else st = mid+1;
}
}
return 0;
}
};
[3,4,5,6,1,2] , [4,5,0,1,2,3]는 통과[4,5,6,7] 는 TLE 뜨고 있으며 output으로 0 나옴...WHY : 왜 틀린 접근인지
st, en, mid 가 같을 경우를 대비 안함HOW : 어떻게 해결하였는지
=을 조건에 추가함
class Solution {
public:
int findMin(vector<int> &nums) {
int st = 0, en = nums.size()-1;
int mid;
if (en == 1) {
int res = nums[0] < nums[1]? nums[0] : nums[1];
return res;
}
while (st <= en) {
mid = (st + en) / 2;
int st_ = nums[st], en_ = nums[en], mid_ = nums[mid];
if (st_ >= mid_) {
if (en_ >= mid_) return mid_;
}
else if (st_ < mid_) {
if (en_ >= mid_) en = mid-1;
else st = mid+1;
}
}
return nums[mid];
}
};
[2, 1] 에서 output이 2로 출력됨int res = nums[0] < nums[1]? nums[0] : nums[1]; 와 같은 꼼수 씀[2, 3, 4, 5, 1]에서 막힘 (5가 출력됨)WHY : 왜 틀린 접근인지
while (st <= en) 안에서 if (st_ >= mid_) { if (en_ >= mid_) return mid_; } 부분에 else가 없음. en_ < mid_인 경우엔 아무 동작도 안 하고 그냥 다음 반복으로 넘어가버림. → 이 경우에는 갱신xwhile 조건이 참이라서 무한루프HOW : 어떻게 해결하였는지
st_, mid_, en_ 세 값을 다 비교하는 방식 대신, mid랑 en(오른쪽 끝)만 비교하는 표준 이분탐색으로 단순화class Solution {
public:
int findMin(vector<int> &nums) {
int st = 0, en = nums.size()-1;
int mid;
while (st <= en) {
mid = (st + en) / 2;
int st_ = nums[st], en_ = nums[en], mid_ = nums[mid];
if (mid_ > en_) st = mid + 1;
else if (mid_ < en_) en = mid;
else return mid_;
}
return nums[mid];
}
};
후기
st, en, mid 세 값 전부 비교하는 방식만 풀어서 이렇게 중간 mid 와 한쪽 끝 en 만 비교하는 건 처음 풀어봐서 떠올리기 어려웠음
결국 제일 작은 수 찾는 문제 맞나요?