数组类问题

NO1 两个有序数组的交集,时间复杂度O(m+n)

NO2 给出多个pair数组,合并有重叠的区间,并输出最大区间的pair


NO1 两个有序数组的交集,时间复杂度O(m+n)

# 拼多多算法面试题
# 求两个已经排好序的数组的交集,要求算法复杂度O(m+n)
# 不能使用两个 for 循环,算法复杂度为O(m*n)
# 我当时的解决思路:使用 in 来做,但 in 的复杂度是 O(n),总的复杂度还是O(m*n),但这个不用事先排好序
int mixed(int arr1[], int n1, int arr2[], int n2, int* mix)
{
    int i = 0;
    int j = 0;
    int k = 0;
    //mix = new int[n1];  
    while (i < n1 && j < n2)
    {
        if (arr1[i] == arr2[j])
        {
            mix[k++] = arr1[i];
            //k++;  
            i++;
            j++;
        }
        else if (arr1[i]>arr2[j])
            j++;
        else if (arr1[i]<arr2[j])
            i++;
    }
    return k;
}


int main() {
    int *m = NULL; //存储相同元素的指针  
    int num;//存储两个数组相同元素个数  
    int a[] = { 0, 1, 2, 3, 4 };
    int b[] = { 1, 3, 5, 7, 9 };
    int len1 = sizeof(a) / sizeof(a[0]);
    int len2 = sizeof(b) / sizeof(b[0]);
    m = new int[len1];
    num = mixed(a, len1, b, len2, m);
    printf("两数组相同元素个数:  %d\n", num);
    printf("相同元素为:\n");
    for (int i = 0; i < num; i++)
        printf("%d \t", m[i]);

    system("pause");
    return 0;
}


NO2 给出多个pair数组,合并有重叠的区间,并输出最大区间的pair

示例:

有 [1,3],[2,6],[8,10],[15,18],

返回 [1,6],[8,10],[15,18].

方法1: 别人做法,将所有合并的子集输出来,更简便

typedef pair<int, int> P;
bool compare(P A, P B)
{
    if (A.first < B.first)
        return true;
    else
        return false;
}

vector<P> merge(vector<P> arr)
{
    vector<P> result;
    if (arr.empty()){
        return result;
    }
    sort(arr.begin(), arr.end(), compare);
    int i = 0, k = 0;
    result.push_back(arr[0]);
    for (int i = 1; i < arr.size(); i++)
    {
        if (arr[i].first>result.back().second){
            result.push_back(arr[i]);
        }
        else{
            result.back().second = max(result.back().second, arr[i].second);
        }
    }
    return result;
}

int main() {
    vector<P> vec, allP;
    vec.push_back(make_pair(1, 3));
    vec.push_back(make_pair(2, 6));
    vec.push_back(make_pair(8, 10));
    vec.push_back(make_pair(15, 18));
    vector<P> result = merge(vec);
    system("pause");
    return 0;
}

方法2 我自己做法,只求出最大的合并的子集,笨一些

typedef pair<int, int> P;
bool compare(P A, P B)
{
    if (A.first < B.first)
        return true;
    else
        return false;
}

P MaxRange(vector<P> vec, int len, set<P> &allP)//用set是为了去重
{
    sort(vec.begin(), vec.end(), compare);
    P Tmp = vec[0];
    P Res = vec[0];//忘掉初始化就错了
    for (int i = 1; i < len; i++)//三种情况,分别落在后一个p的头尾区间的左中右三种情况!
    {
        if (vec[i - 1].second < vec[i].first)//前一个P的尾在后一个P的尾巴的左边
        {
            Tmp.second = vec[i - 1].second;
            allP.insert(Tmp);//防止漏掉第一个pair
            Tmp = vec[i];
        }
        else if ((vec[i - 1].second >= vec[i].first) && (vec[i - 1].second <= vec[i].second))//前一个P的尾巴在后一个P的尾巴的右边,在后一个P的头的左边
        {
            Tmp.second = vec[i].second;
        }
        else if (vec[i - 1].second>vec[i].second)//前一个P的尾巴在后一个P的尾巴的右边
        {
            Tmp.second = vec[i - 1].second;
        }
        
        allP.insert(Tmp);


        if ((Res.second - Res.first) < (Tmp.second - Tmp.first))//每个循环都要比一遍得出当前循环的最大区间
        {
            Res = Tmp;
        }
    }
    return Res;
}




int main() {
    vector<P> vec;
    set<P> allP;
    vec.push_back(make_pair(-2, 3));
    vec.push_back(make_pair(2, 6));
    vec.push_back(make_pair(7, 14));
    vec.push_back(make_pair(15, 118));
    cout << MaxRange(vec, vec.size(), allP).first << "   " << MaxRange(vec, vec.size(), allP).second << endl;

    system("pause");
    return 0;
}

方法3  用multiset来做,但是有问题,估计方法2也有相同的问题,allP存了(7,14)(7,118)


typedef pair<int, int> P;
bool compare(P A, P B)
{
    if (A.first < B.first)
        return true;
    else
        return false;
}

P MaxRange1(multiset<P> vec, set<P> &allP)
{
    multiset<P>::iterator ite = vec.begin();
    P res = *ite;
    P tmp = *ite;
    ite++;
    for (; ite != vec.end(); ite++)
    {
        if ((*ite).first > tmp.second)
        {
            allP.insert(tmp);
            tmp = *ite;
        }
        else
        {
            tmp.second = max(tmp.second, (*ite).second);
        }

        allP.insert(tmp);

        if ((tmp.second - tmp.first) > (res.second - res.first))
        {
            res = tmp;
        }

    }
    return res;
}


int main() {
    multiset<P> vec;
    set<P> allP;
    vec.insert(make_pair(-20, 1));
    vec.insert(make_pair(10, 118));
    vec.insert(make_pair(7, 14));
    vec.insert(make_pair(2, 6));
    cout << MaxRange1(vec, allP).first << "   " << MaxRange1(vec, allP).second << endl;

    system("pause");
    return 0;
}

方法4  貌似这样可以

#include<iostream>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include <assert.h>
#include <algorithm>
#include <map>
#include <string>
#include <set>
#include <numeric>
#include <sstream>
#include <unordered_set>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

typedef pair<int, int> P;
bool compare(P A, P B)
{
    if (A.first < B.first)
        return true;
    else
        return false;
}

P MaxRange1(multiset<P> vec, set<P> &allP)
{
    multiset<P>::iterator ite = vec.begin();
    P res = *ite;
    P tmp = *ite;
    ite++;
    for (; ite != vec.end(); ite++)
    {
        if ((*ite).first > tmp.second)
        {
            allP.insert(tmp);
            tmp = *ite;
        }
        else
        {
            tmp.second = max(tmp.second, (*ite).second);
            allP.insert(tmp);
        }

        

        if ((tmp.second - tmp.first) > (res.second - res.first))
        {
            res = tmp;
        }

    }
    return res;
}


int main() {
    multiset<P> vec;
    set<P> allP;
    vec.insert(make_pair(-20, 1));
    vec.insert(make_pair(10, 118));
    vec.insert(make_pair(7, 14));
    vec.insert(make_pair(2, 6));
    cout << MaxRange1(vec, allP).first << "   " << MaxRange1(vec, allP).second << endl;

    system("pause");
    return 0;
}







猜你喜欢

转载自blog.csdn.net/longlovefilm/article/details/79822102