C++程序搜索已排序旋转数组中的元素
给定一个已排序的数组,该数组围绕一个点旋转。我们还给定一个键在数组中进行搜索。在该旋转数组中搜索元素所采用的逻辑为:
首先,我们找到数组的中间元素。如果键存在,则返回键存在于数组中。
如果键不存在于中间位置,我们可以查看数组的左半部分(从左到中间)是否已排序。如果已排序,则可以在左半部分搜索键,否则,可以在右半部分(mid+1,right)进行搜索。
如果键在中间位置未找到且左半部分未排序,则我们会对右半部分进行排序,并查看键是否存在于右半部分,或者将在数组的左侧进行搜索。
否则,返回未找到。
让我们看看下面的一些输入输出场景:
假设有一个包含元素的数组。例如,2、5、7、9、11,旋转后变为 5、9、11、2、7。假设数组的键为 2。
Input: arr[] = {5, 9, 11, 2, 7}, Key=2 Output: Element "2" found at 3rd index
让我们假设另一种场景,其中键不在指定的数组中。
Input: arr[] = {10, 23, 45, 77, 84}, Key=90 Output: Element "90" not found.
算法
以下步骤是方法。
找到数组的中间元素。
将数组分成两部分。(mid = left + right)/ 2
检查键是否为中间元素。
否则,检查数组左半部分中的元素是否已排序
否则,检查右半部分(mid+1,right)中的元素
否则,对左半部分进行排序并检查
否则,返回元素未找到。
示例
例如,假设我们有一个数组“2,3,4,5,6,7,8”,旋转后的数组为“5, 6, 7, 8, 2, 3, 4”。该数组的键为 2。
此操作的 C++ 实现如下:
#include <iostream> #include <vector> using namespace std; bool solve(vector<int> arr, int left, int right, int key) { if (left > right) { return false; } int mid = (left + right)/2; if (arr[mid] == key) { return true; } if (arr[left] <= arr[mid]) { if (key >= arr[left] && key <= arr[mid]) { return solve(arr, left, mid-1, key); } return solve(arr, mid+1, right, key); } if (key >= arr[mid] && key <= arr[right]) return solve(arr, mid+1, right, key); return solve(arr, left, mid-1, key); } int main() { vector<int> arr = {5, 6, 7, 8, 2, 3, 4}; int key = 2; if(solve(arr, 0, arr.size()-1, key)) cout << key << " is present"; else cout << key << " is not present"; return 0; }
输出
2 is present
结论
解决此问题的另一种方法是找出枢轴点或数组围绕其旋转的索引,然后对该侧进行二分查找。我们的方法只需要一次二分查找即可解决问题。每当我们看到搜索和已排序的数组时,都应该将二分查找作为一种方法。
广告