面试题:在数组里查找这样的数,它大于(等于)左侧所有数,小于(等于)右侧所有数

Posted 夏夕空~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题:在数组里查找这样的数,它大于(等于)左侧所有数,小于(等于)右侧所有数相关的知识,希望对你有一定的参考价值。

方法一

  • 从左向右遍历一遍,得到数组left_maxleft_max[i]表示原数组nums中第i个元素左边(不包括nums[i])的最大值。
  • 从右往左遍历一遍,得到数组right_minright_min[i]表示原数组nums中第i个元素右边(不包括nums[i])的最小值。
  • 从左向右遍历,判断nums[i]left_max[i], right_min[i]的大小关系。

方法二

事实上,上面的第一次遍历可以合并进最后一次遍历中,且只需要用一个变量left_max表示当前元素左边的最大值即可,这样只需要遍历两遍。

  • 从右往左遍历一遍,得到数组right_minright_min[i]表示原数组nums中第i个元素右边(不包括nums[i])的最小值。
    从左向右遍历,判断nums[i]left_max, right_min[i]的大小关系,并更新left_max

需要注意的几个地方

  1. 左右端点元素是否考虑
  2. 注意大小关系是>/<还是≥/≤
  3. left_max[i]表示原数组nums中第i个元素左边(不包括nums[i])的最大值。 right_min[i]表示原数组nums中第i个元素右边(不包括nums[i])的最小值。

若包括的话,有可能nums[i]会覆盖掉其左右两边的最大/最小值的信息,建议不包括。

C++代码

#include<iostream>
#include<vector>
using namespace std;

void printVec(const vector<int> nums){
    for(auto num:nums)
        cout<<num<<" ";
    cout<<endl;
}

vector<int> leftMax(const vector<int> nums){
    int n=nums.size();
    vector<int> left_max(n, 0x80000000);
    for(int i=1;i<n;i++){
        left_max[i]=max(left_max[i-1], nums[i-1]);
    }
    return left_max;
}

vector<int> rightMin(const vector<int> nums){
    int n=nums.size();
    vector<int> right_min(n, 0x7FFFFFFF);
    for(int i=n-2;i>=0;i--){
        right_min[i]=min(right_min[i+1], nums[i+1]);
    }
    return right_min;
}

vector<int> findNum1(const vector<int> nums, bool end=false){
    vector<int> res;
    int n=nums.size();

    vector<int> left_max=leftMax(nums);
    vector<int> right_min=rightMin(nums);

    if(end){
        //考虑两个端点的情况
        for(int i=0;i<n;i++){
            //注意是>/<还是≥/≤
            if(nums[i]>=left_max[i]&&nums[i]<=right_min[i]){
                res.emplace_back(nums[i]);
            }
        }
    }
    else{
        //不考虑两个端点的情况
        for(int i=1;i<n-1;i++){
            //注意是>/<还是≥/≤
            if(nums[i]>=left_max[i]&&nums[i]<=right_min[i]){
                res.emplace_back(nums[i]);
            }
        }
    }
    return res;
}

//left_min在向右遍历过程中便可实时更新,不需要用数组保存
vector<int> findNum2(const vector<int> nums, bool end=false){
    vector<int> res;   
    int n=nums.size();
    if(!n) return res;

    vector<int> right_min=rightMin(nums);

    if(end){
        //考虑两个端点的情况
        int left_max=0x80000000;
        for(int i=0;i<n;i++){
            //注意是>/<还是≥/≤
            if(nums[i]>=left_max&&nums[i]<=right_min[i]){
                res.emplace_back(nums[i]);
            }
            left_max=max(left_max, nums[i]);
        }
    }
    else{
        //不考虑两个端点的情况
        int left_max=nums[0];
        for(int i=1;i<n-1;i++){
            //注意是>/<还是≥/≤
            if(nums[i]>=left_max&&nums[i]<=right_min[i]){
                res.emplace_back(nums[i]);
            }
            left_max=max(left_max, nums[i]);
        }
    }
    return res;
}

int main(){

    vector<int> nums={1,2,2,3,4,4,5};

    vector<int> res1=findNum1(nums);
    vector<int> res2=findNum2(nums);

    vector<int> res3=findNum1(nums, true);
    vector<int> res4=findNum2(nums, true);

    printVec(nums);
    cout<<endl;
    printVec(res1);
    printVec(res2);
    cout<<endl;
    printVec(res3);
    printVec(res4);

    system("pause");
    return 0;
}

以上是关于面试题:在数组里查找这样的数,它大于(等于)左侧所有数,小于(等于)右侧所有数的主要内容,如果未能解决你的问题,请参考以下文章

面试题:在数组里查找这样的数,它大于(等于)左侧所有数,小于(等于)右侧所有数

面试题:在数组里查找这样的数,它大于(等于)左侧所有数,小于(等于)右侧所有数

面试题目4:二维数组中的查找

数据结构与算法面试题80道(14)

Java面试题——素数

剑指Offer编程题(Java实现)——二维数组中的查找