两个数组包含
来源:互联网 发布:淘宝儿童玩具 编辑:程序博客网 时间:2024/06/05 03:46
http://blog.csdn.net/yysdsyl/article/details/5421200
题目:
You have given two arrays, say
A: 4, 1, 6, 2, 8, 9, 5, 3, 2, 9, 8, 4, 6
B: 6, 1, 2, 9, 8
where B contains elements which are in A in consecutive locations but may be in any order.
Find their starting and ending indexes in A. (Be careful of duplicate numbers).
answer is (1,5)
先给出代码,再结合代码解释,如下:
- #include <iostream>
- #include <map>
- using namespace std;
- void FindConsecutiveSubarrLocation(int A[], int lenA, int B[], int lenB)
- {
- map<int, int> bmap;
- map<int, int> windowmap;
- map<int, int> diffmap;
- for(int i = 0; i< lenB; i++)
- {
- if(bmap.count(B[i]) == 0)
- bmap[B[i]] = 1;
- else
- ++bmap[B[i]];
- if(windowmap.count(A[i]) == 0)
- windowmap[A[i]] = 1;
- else
- ++windowmap[A[i]];
- }
- map<int, int>::iterator it = bmap.begin();
- int sameElement = 0;
- while(it != bmap.end())
- {
- if(windowmap.count((*it).first) != 0)
- {
- diffmap[(*it).first] = windowmap[(*it).first] - (*it).second;
- if(diffmap[(*it).first] == 0)
- sameElement++;
- }
- else
- diffmap[(*it).first] = -(*it).second;;
- it++;
- }
- if(sameElement == lenB)
- {
- cout<<"----------find one---------"<<endl;
- cout<<"start index:"<<0<<endl;
- cout<<"end index:"<<lenB-1<<endl;
- }
- for(int i = lenB; i < lenA; i++)
- {
- if(diffmap.count(A[i-lenB]) != 0)
- {
- diffmap[A[i-lenB]]--;
- if(diffmap[A[i-lenB]] == 0)
- sameElement++;
- else if(diffmap[A[i-lenB]] == -1)
- sameElement--;
- }
- if(diffmap.count(A[i]) !=0)
- {
- diffmap[A[i]]++;
- if(diffmap[A[i]] == 0)
- sameElement++;
- else if(diffmap[A[i]] == 1)
- sameElement--;
- }
- if(sameElement == diffmap.size())
- {
- cout<<"----------find one---------"<<endl;
- cout<<"start index:"<<i-lenB+1<<endl;
- cout<<"end index:"<<i+1<<endl;
- }
- }
- }
- int main()
- {
- int A[] = {4, 1, 2, 1, 8, 9, 2, 1, 2, 9, 8, 4, 6};
- int B[] = {1, 1, 2, 8, 9};
- int lenA = sizeof(A)/sizeof(int);
- int lenB = sizeof(B)/sizeof(int);
- FindConsecutiveSubarrLocation(A, lenA, B, lenB);
- return 0;
- }
思路:
ex,
int A[] = {4, 1, 2, 1, 8, 9, 5, 3, 2, 9, 8, 4, 6};
int B[] = {1, 1, 2, 8, 9};
int lenA = 13;
int lenB = 5;
map<int,int> bmap;
map<int,int> windowmap;
map<int,int> diffmap;
首先初始化map:
bmap = {1:2, 2:1, 8:1,9:1}
windowmap = {1:2, 2:1, 4:1,8:1}
diffmap = {1:0, 2:0, 8:0, 9:-1}
其中"1: 0" 意味着数组A的当前滑动窗口正好和数组B包含相同数量的"1",而 " 9:-1" 则表示A当前的滑动窗口和B比较缺少1个"9"。 并且我们注意到diffmap和bmap拥有相同的key
代码中的变量"sameElement"代表的是diffmap中有多少pair与bmap匹配, 显然,初始化后的“sameElement”变量值会是3 ( 1:0, 2:0, 8:0 in diffmap).
接下来
在数组A中滑动size为lenB的窗口,没向前滑动一步,只需check滑动窗口左侧划出的元素El和右侧滑入的元素Er,更新diffmap和sameElement,如下:
if(diffmap.count(A[i-lenB]) != 0)
{
diffmap[A[i-lenB]]--;
if(diffmap[A[i-lenB]] == 0)
sameElement++;
else if(diffmap[A[i-lenB]] == -1)
sameElement--;
}
if(diffmap.count(A[i]) !=0)
{
diffmap[A[i]]++;
if(diffmap[A[i]] == 0)
sameElement++;
else if(diffmap[A[i]] == 1)
sameElement--;
}
if(sameElement == diffmap.size())
{
cout<<"----------find one---------"<<endl;
cout<<"start index:"<<i-lenB+1<<endl;
cout<<"end index:"<<i+1<<endl;
}
这个题目有一个陷阱,就是B数组可能有重复的数字。
上面的思路很精妙,既然要求B中的元素在A中连续出现,则A中的窗口就是B的大小。每次就是减少窗口最左边的元素,增加窗口最右边的元素
但是,上面的算法有些错误,47和55行,不应该判断是否为0,而是直接--或者直接++
- 两个数组包含
- 数组包含
- 编写一个程序,输入两个包含 5 个元素的数组,先将两个数组升序排序,然 后将这两个数组合并成一个升序数组(合并排序)。
- 两个字符串是否包含
- 两个字符串包含算法
- C#--如何在一个函数中返回两个值(包含数组的参数)
- 349. Intersection of Two Arrays (求两个数组的交集,不包含重复元素)
- 350. Intersection of Two Arrays II (求两个数组的交集,包含重复元素)
- 编写将一个包含有20个数据的数组M分成两个数组,正整数数组P和负数数组N ,分别把这两个数组中的数据的个数显示出来
- 判断两个集合包含关系
- 互相包含的两个类
- C++两个类互相包含
- 两个字符串是否包含问题
- 两数组包含问题
- js判断数组包含
- 数组包含问题
- 两数组包含问题
- 判断数组是否包含
- sysfs方式实现马达驱动
- servlet用户管理项目
- win8安装Qt+mysql+qt编译mysql驱动+测试实例解析4.8.2
- C# Webclient 文件远程上传
- Storyboard
- 两个数组包含
- linux echo设置颜色
- Android中Fragment的应用
- 腾讯QQ空间g_tk算法
- 关于Struts2异常或错误不输出到控制台原因
- DP开发总结2
- Gold Balanced Lineup poj3274
- hdu 3068 最长回文
- Hibernate概况