Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 查找数组中先增大后减小的最大元素_C_Algorithm_Data Structures_Binary Search - Fatal编程技术网

C 查找数组中先增大后减小的最大元素

C 查找数组中先增大后减小的最大元素,c,algorithm,data-structures,binary-search,C,Algorithm,Data Structures,Binary Search,我做了一个代码,为下面的输入编译,它是正确的 作为 产量:500 Input: arr[] = {1, 3, 50, 10, 9, 7, 6} 产量:50 int findIncre_Decre(int arr[], int low, int high) { if (low == high) return arr[low]; /* If there are two elements and first is greater then

我做了一个代码,为下面的输入编译,它是正确的 作为

产量:500

 Input: arr[] = {1, 3, 50, 10, 9, 7, 6}
产量:50

int findIncre_Decre(int arr[], int low, int high)
  {
        if (low == high)
        return arr[low];

       /* If there are two elements and first is greater then
          the first element is maximum */
         if ((high == low + 1) && arr[low] >= arr[high])
                return arr[low];

         /* If there are two elements and second is greater then
             the second element is maximum */
             if ((high == low + 1) && arr[low] < arr[high])
                 return arr[high];

               int mid = (low + high)/2; /*low + (high - low)/2;*/

          /* If we reach a point where arr[mid] is greater than both of
           its adjacent elements arr[mid-1] and arr[mid+1], then arr[mid]
            is the maximum element*/
       if ( arr[mid] > arr[mid + 1] && arr[mid] > arr[mid - 1])
            return arr[mid];

       if (arr[mid] > arr[mid + 1] && arr[mid] < arr[mid - 1])
         return findIncre_Decre(arr, low, mid-1);
         else 
        return findIncre_Decre(arr, mid + 1, high);
   }
预期产量:-

15 
但我得到的答案是16而不是15

任何想法都将不胜感激


提前感谢。

为什么它会起作用?编写代码时假设数组可以分为两部分:一部分是递增部分,另一部分是递减部分。此测试用例打破了先决条件

您可以检查数组是否有效,但在最坏的情况下,需要进行线性扫描。最好是简单地检查每个元素,以找到最大的元素

举个例子,检查输入是否正确并不总是好的。对于这个特殊的问题,如果您想在O(logN)中解决它,就必须假设输入是正确的


edit:为了公平起见,这个答案被编辑了。在原始答案中,我给了OP一个测试用例,以帮助他们找到代码失败的地方,但我的测试用例也是无效的。)

正如@Rafael Giusti在编写程序时所说的,我们也必须尝试捕获无效输入

我已经添加了错误处理问题的解决方案(无效情况下数组中的最大元素)。上述问题可以通过以下方式解决:

  • 通过线性搜索(取O(n))
  • 通过二进制搜索(需要O(long))
  • 线性方法

    1.对于无效输入,我在数组中抛出最大元素

    2.对于这个问题,数组中至少需要三个元素

    注意:我只是检查边缘情况,比如(数组中少于三个元素,按升序排列,按降序排列)。您可以完全迭代数组以检查给定数组是否满足条件-首先增加-然后减少,我在下面的程序中没有检查-如果不满足边缘情况,我只是返回数组中的最大元素

    int findElement(int arr[], int low, int high) {
         if(low < 0 || low >= high || low+1 == high) return (arr[low] < arr[high] ? arr[high] : arr[low];
         int max = arr[low];
         for(int i=low+1; i<=high-1 && low-1 <= high; i++) {
             max = arr[i] > max ? arr[i] : max;
             if(arr[i-1] < arr[i] && arr[i] > arr[i+1]) 
                return arr[i];   //Perfect match !!
         }
        return max;    // We haven't found any element 
    }
    
    int-findElement(int-arr[],int-low,int-high){
    如果(低<0 | |低>=高| |低+1==高)返回(arr[low]
    二进制搜索方法

    注意:在数组输入无效的情况下返回最大值

    int findElement(int arr[], int low, int high) {
         if(high < low) return arr[low];
         if(high-low < 2) return (arr[low] > arr[high]) ? arr[low] : arr[high];     
         int mid = (low + high)/2;
         int left = findElement(arr, low, mid-1);
         int right = findElement(arr, mid+1, high);
         return (left < arr[mid]) && (right < arr[mid]) ? arr[mid] : (left > right ? left : right);
    }
    
    int-findElement(int-arr[],int-low,int-high){
    if(高<低)返回arr[低];
    如果(高-低<2)返回(arr[low]>arr[high])?arr[low]:arr[high];
    int mid=(低+高)/2;
    int left=findElement(arr、low、mid-1);
    int right=findElement(arr,中+1,高);
    返回(左右?左:右);
    }
    
    你的问题是数组会先增大然后减小…但是你的输入数组有随机数的集合…似乎是矛盾的!它不起作用,因为输入数组不适合先增大然后减小的条件。
    @MBo抱歉,我知道了,谢谢你。你的数组y不应包含随机数。示例中的16不合适。使用此设置,只需在随机数组中查找最大的数即可(因为最大的数将被较小的数包围,这意味着它在该特定部分先增大后减小)。这只是一个线性搜索;只有当你很好地了解数组的属性时,你才能进行一种形式的二元搜索。如果它先增大后减小,没有任何偏差,二元搜索就可以正常工作。这个答案是错误的。线性版本只搜索递增/递减序列的边界。它不会在OP自己的测试用例!当简单的线性扫描和OP的版本适用于小到1的数组时,它还要求数组的大小为3。检查无效输入的唯一方法是运行整个数组,依次验证每个元素。如果数组几乎正确,则任何其他替代方法都将失败,但在某些部分违反了规则,即算法决定不验证,因为它放弃了第一个或没有分支。@giusti线性搜索只验证了两种无效情况,例如1)对于这个问题,数组大小必须最小为3;2)如果序列在整个过程中增加,或3)给定序列在整个过程中减少)。对于像随机数序列这样的情况,这将不会验证-对于这种情况,您必须遍历整个数组来验证输入数组。此外,这不是线性搜索的精确实现。我们正在使用线性搜索来解决我们的问题。在这里,我们添加了验证标准,比如搜索应该只适用于最小长度为3的数组。希望你能理解……我能理解。但是,只验证一些测试用例对您来说没有多大意义。如果序列是
    {1,0,-1,4}
    ,则代码返回
    -1
    ;如果序列是
    {1,2,-1,4}
    ,则代码返回
    -2
    。两者都是无效的输入,但是如果用户信任您的函数,他们会认为其中一个是有效的。您应该以一致的方式验证和检测错误,或者在假设输入有效的情况下让算法运行。@giusti用户已经给了一个正数数组(我的示例接受并返回正数)。如果他/她在数组中有负数,则他们必须使用其他值来验证无效案例。。
    int findElement(int arr[], int low, int high) {
         if(low < 0 || low >= high || low+1 == high) return (arr[low] < arr[high] ? arr[high] : arr[low];
         int max = arr[low];
         for(int i=low+1; i<=high-1 && low-1 <= high; i++) {
             max = arr[i] > max ? arr[i] : max;
             if(arr[i-1] < arr[i] && arr[i] > arr[i+1]) 
                return arr[i];   //Perfect match !!
         }
        return max;    // We haven't found any element 
    }
    
    int findElement(int arr[], int low, int high) {
         if(high < low) return arr[low];
         if(high-low < 2) return (arr[low] > arr[high]) ? arr[low] : arr[high];     
         int mid = (low + high)/2;
         int left = findElement(arr, low, mid-1);
         int right = findElement(arr, mid+1, high);
         return (left < arr[mid]) && (right < arr[mid]) ? arr[mid] : (left > right ? left : right);
    }