华为笔试:

题目描述:

输入两个整数数组A和B,二者中元素都满足唯一且无序,同时A中的元素在B中都存在,B中元素在A中也存在,即A和B仅仅元素顺序可能不同,比如(1,3,5,2)和(3,2,1,5)。

现在想通过分别删除A和B中的部分元素,使得A和B剩下的子序列完全相同,请输出数组A需要删除的最少元素数(注意数组B需要删除相同数量的元素)。

输入描述:

输入共三行,第一行为一个整数n(1<=n<=100000),表示A和B中元素的个数。第二行为数组A,共n个整数,第三行为数组B,共n个整数。

输出描述:

输出一行为数组A需要删除的元素数(包含换行)。

输入:

4

1 3 5 2

3 2 1 5

输出:

2

说明:

{1, 3, 5, 2}和{3, 2, 1, 5}的最长公共子序列有三个。分别为{1, 5}, {3, 5}, {3, 2},所以至少需要删除2个元素。

思路分析:

首先用一个哈希表保存每个元素在A数组中的位置,接下来根据B的输入,利用A数组来保存对应元素的B中的位置。实质上对于A,B是需要查找二者相等元素的最长上升序列。

代码:

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<string>
 6 #include<map>
 7 #include<limits.h>
 8 #include<queue>
 9 using namespace std;
10 
11 int LIS(vector<int>&A, vector<int>&B)
12 {
13     int len=1;
14     B[0]=A[0];
15     for(int i=1; i<A.size(); i++)
16     {
17         if(A[i]>B[len-1])
18             B[len++]=A[i];
19         else
20         {
21             int p = lower_bound(B.begin(), B.begin()+len, A[i])-B.begin();
22             B[p] = A[i];
23         }
24     }
25     return len;
26 }
27 
28 int main()
29 {
30     int n;
31     cin>>n;
32     vector<int>A(n);
33     vector<int>B(n);
34     map<int, int>M;
35     for(int i=0; i<n; i++)
36     {
37         cin>>A[i];
38         M[A[i]]=i;
39     }
40     int k=0;
41     for(int i=0; i<n; i++)
42     {
43         int x;
44         cin>>x;
45         A[M[x]] = k++;
46     }
47     int ans = n-LIS(A,B);
48     cout<<ans<<endl;
49     return 0;
50 }

猜你喜欢

转载自www.cnblogs.com/LJ-LJ/p/11455673.html