两个数组包含

来源:互联网 发布:淘宝儿童玩具 编辑:程序博客网 时间: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)

 

先给出代码,再结合代码解释,如下:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <map>  
  3.   
  4. using namespace std;  
  5.   
  6. void FindConsecutiveSubarrLocation(int A[], int lenA, int B[], int lenB)  
  7. {  
  8.     map<intint> bmap;  
  9.     map<intint> windowmap;  
  10.     map<intint> diffmap;  
  11.     for(int i = 0; i< lenB; i++)  
  12.     {  
  13.         if(bmap.count(B[i]) == 0)  
  14.             bmap[B[i]] = 1;  
  15.         else  
  16.             ++bmap[B[i]];  
  17.         if(windowmap.count(A[i]) == 0)  
  18.             windowmap[A[i]] = 1;  
  19.         else  
  20.             ++windowmap[A[i]];  
  21.     }  
  22.   
  23.     map<intint>::iterator it = bmap.begin();  
  24.     int sameElement = 0;  
  25.     while(it != bmap.end())  
  26.     {  
  27.         if(windowmap.count((*it).first) != 0)  
  28.         {  
  29.             diffmap[(*it).first] = windowmap[(*it).first] - (*it).second;  
  30.             if(diffmap[(*it).first]  == 0)  
  31.                 sameElement++;  
  32.         }  
  33.         else  
  34.             diffmap[(*it).first] = -(*it).second;;  
  35.         it++;  
  36.     }  
  37.   
  38.     if(sameElement == lenB)  
  39.     {  
  40.         cout<<"----------find one---------"<<endl;  
  41.         cout<<"start index:"<<0<<endl;  
  42.         cout<<"end index:"<<lenB-1<<endl;  
  43.     }  
  44.   
  45.     for(int i = lenB; i < lenA; i++)  
  46.     {  
  47.         if(diffmap.count(A[i-lenB]) != 0)  
  48.         {  
  49.             diffmap[A[i-lenB]]--;  
  50.             if(diffmap[A[i-lenB]] == 0)  
  51.                 sameElement++;  
  52.             else if(diffmap[A[i-lenB]] == -1)  
  53.                 sameElement--;  
  54.         }  
  55.         if(diffmap.count(A[i]) !=0)  
  56.         {  
  57.             diffmap[A[i]]++;  
  58.             if(diffmap[A[i]] == 0)  
  59.                 sameElement++;  
  60.             else if(diffmap[A[i]] == 1)  
  61.                 sameElement--;  
  62.         }  
  63.         if(sameElement == diffmap.size())  
  64.         {  
  65.             cout<<"----------find one---------"<<endl;  
  66.             cout<<"start index:"<<i-lenB+1<<endl;  
  67.             cout<<"end index:"<<i+1<<endl;  
  68.         }  
  69.     }  
  70. }  
  71.   
  72. int main()  
  73. {  
  74.     int A[] = {4, 1, 2, 1, 8, 9, 2, 1, 2, 9, 8, 4, 6};  
  75.     int B[] = {1, 1, 2, 8, 9};  
  76.     int lenA = sizeof(A)/sizeof(int);  
  77.     int lenB = sizeof(B)/sizeof(int);  
  78.     FindConsecutiveSubarrLocation(A, lenA, B, lenB);  
  79.     return 0;  
  80. }  

 

 

思路:

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,而是直接--或者直接++