转载自http://www.acmerblog.com/whether-an-array-is-subset-of-another-array-6007.html
判断一个数组是另外一个数组的子集
给定两个数组:给两个数组:arr1[0..m-1] 和arr2[0..n-1]. 判断arr2是否是arr1的一个子集合,两个数组都是未排序的。
1)最简单的办法就是暴力循环。
两重循环
#include<stdio.h>
bool isSubset(int arr1[], int arr2[], int m, int n)
{
int i = 0;
int j = 0;
for (i=0; i<n; i++)
{
for (j = 0; j<m; j++)
{
if(arr2[i] == arr1[j])
break;
}
if (j == m)
return 0;
}
return 1;
}
int main()
{
int arr1[] = {11, 1, 13, 21, 3, 7};
int arr2[] = {11, 3, 7, 1};
int m = sizeof(arr1)/sizeof(arr1[0]);
int n = sizeof(arr2)/sizeof(arr2[0]);
if(isSubset(arr1, arr2, m, n))
printf("arr2[] is subset of arr1[] ");
else
printf("arr2[] is not a subset of arr1[]");
return 0;
}
2)排序+比较
先用快排排序,再比较
arr1和arr2。分三种情况,直到某一个数组结束。
(1)如果arr1的元素大于arr2,则说明arr1后面没有元素能够和arr2匹配了,可以立即返回
(2)如果arr1的元素小于arr2,则说明arr1应该往后面移,而arr2的位置不变
(3)如果arr1的元素等于arr2,则arr1往后面移,arr2往后面移
结束的条件是:判断arr2的下标是否达到了最后一位,如果是的话,表明匹配成功,否则返回失败
代码:
bool isSubset(int arr1[], int arr2[], int m, int n)
{
int i = 0, j = 0;
if(m < n)
return 0;
quickSort(arr1, 0, m-1);
quickSort(arr2, 0, n-1);
while( i < n && j < m )
{
if( arr1[j] <arr2[i] )
j++;
else if( arr1[j] == arr2[i] )
{
j++;
i++;
}
else if( arr1[j] > arr2[i] )
return 0;
}
if( i < n )
return 0;
else
return 1;
}
3)hash表
对arr1中的数组建个hash表,value值表示hash的次数,然后依次判断arr2中的元素是否存在,并且存在则对value的数值减去1。
用vaule的值来记录次数,主要是防止重复,因为像暴力破解的方法是没法解决重复的问题。因为当arr2遍历到一个数a的时候,arr2的下标往后移动一位,如果下一位还是a,从arr1开始遍历a的时候就以为有两个a,其实是同一个a。
还是挺赞的一道题