卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章20264本站已运行347

在一个已排序且旋转的数组中搜索元素的C++程序

<?xml encoding="utf-8" ?>

在一个已排序且旋转的数组中搜索元素的C++程序

我们得到一个围绕一个点旋转的排序数组。我们还获得了一个在数组中搜索的键。在这个旋转数组中搜索元素所采用的逻辑是 -

  • 首先,我们找到数组的中间元素。如果密钥存在,则我们返回该密钥存在于数组中。

  • 如果键不在中间,我们可以查看数组的左侧部分(从左到中)是否已排序。如果已排序,则可以在左侧查找 key,否则可以在右侧(mid+1, right)查找

  • 如果中间没有找到key,并且左边部分没有排序,那么我们会对右边部分进行排序,然后我们可以看看右边部分是否存在该key,或者我们会在右边部分进行搜索数组的左侧

  • 否则我们返回找不到。

让我们看看下面的一些输入输出场景 -

想象有一个由其中的元素组成的数组。例如,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.

算法

以下步骤是实现方法。

  • 查找数组的中间元素。

  • 将数组分为两部分。 ( 中 = 左 + 右 ) / 2

  • 检查key是否为中间元素。

  • Else if ,检查数组左侧的元素并且它已排序

  • else if,检查右侧元素(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

结论

解决此问题的另一种方法是找出数组旋转的枢轴点或索引,然后对边进行二分搜索。我们的方法只需要 1 次二分搜索即可解决问题。每当我们看到搜索和排序数组时,我们都应该将二分搜索作为搜索方法之一。

卓越飞翔博客
上一篇: 利用 Rust 强化 PHP:实现更高效的开发流程
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏