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;
}