This commit is contained in:
Sainnhe Park 2022-11-21 20:50:10 +08:00
parent a18ee1e5d7
commit 38a20a3c7f
3 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,14 @@
#ifndef S0033_SEARCH_IN_ROTATED_SORTED_ARRAY
#define S0033_SEARCH_IN_ROTATED_SORTED_ARRAY
#include <vector>
#include <cmath>
using namespace std;
class Solution {
public:
int search(vector<int>& nums, int target);
};
#endif

View File

@ -0,0 +1,50 @@
#include "s0033_search_in_rotated_sorted_array.hpp"
// 看到 O(logN) 的搜索算法,立马想到二分法
// 可是二分法要求数组已排序,旋转数组又如何用二分法呢?
// 思路很简单,对数组二分,有一半一定是有序的,另一半可能有序可能无序
// 对有序的一半进行二分搜索,无序的部分再次进行二分,如此迭代
int Solution::search(vector<int>& nums, int target) {
int size = nums.size();
int left{0};
int right = size - 1;
int mid = static_cast<int>(floor((left + right) / 2));
while (left <= right) {
mid = static_cast<int>(floor((left + right) / 2));
// 数组有序
if (nums[left] <= nums[right]) {
// 越界
if (target > nums[right] || target < nums[left]) {
return -1;
}
// 二分查找
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
} else { // 数组无序
// 左半部分有序
if (nums[mid] >= nums[left]) {
// 如果 target 在左半部分,则更新 right 然后继续迭代
if (target <= nums[mid] && target >= nums[left]) {
right = mid;
} else { // target 位于右半部分或者越界
// 我们不在这里处理越界,因为越界的情况包含在了这个 else
// 语句里,继续迭代下去会出循环,然后返回 -1
left = mid + 1;
}
} else { // 右半部分有序
if (target >= nums[mid] && target <= nums[right]) {
left = mid;
} else {
right = mid - 1;
}
}
}
}
return -1;
}

View File

@ -0,0 +1,27 @@
#include "s0033_search_in_rotated_sorted_array.hpp"
#include <gtest/gtest.h>
TEST(Problem33, Case1) {
vector<int> nums{4, 5, 6, 7, 0, 1, 2};
int target{0};
int o{4};
Solution solution;
EXPECT_EQ(solution.search(nums, target), o);
}
TEST(Problem33, Case2) {
vector<int> nums{4, 5, 6, 7, 0, 1, 2};
int target{3};
int o{-1};
Solution solution;
EXPECT_EQ(solution.search(nums, target), o);
}
TEST(Problem33, Case3) {
vector<int> nums{1};
int target{0};
int o{-1};
Solution solution;
EXPECT_EQ(solution.search(nums, target), o);
}