华为笔试:字符串的删除次数
题目描述:
输入两个整数数组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 }