两个有序数组求交集

假设两个数组 a 和 b,a 的长度为 m ,b 的长度为 n , m < n, 有以下四种解法:

(1)每次从数组 b 中 取一个数,遍历 a 中所有元素进行比较,若相同就保存,这样时间复杂度为O(m*n);
(2)由于数组是有序的,每次从数组 b 中 取一个数,对 a 中元素进行二分查找,若相同就保存,时间复杂度为O(nlog(m));
(3)将 a 中的元素 hash 存储(用map或者dict),遍历 b 中的每一个值看是否在这个hash 中,若存在就保存,时间复杂度是 O(m),空间复杂度是O(n);
(4)a 和 b 两个数组的头部分别维护两个指针,若其中一个比另一个小,则向前移动,若遇到相等时保存,遍历直到其中一个数组的尾部,时间复杂度O(m+n);

第一种方法在此处不再实现,基本不会用到,下面依次给出三种方法的实现。

第(2)中方法的实现:

//二分查找
int binarySearch(vector<int> v, int n, int target)
{
    int l = 0;
    int r = n;
    while(l <= r)
    {
        int m = (l + r) / 2;
        if(v[m] == target)
            return m;
        else if(v[m] > target)
            r = m - 1;
        else 
            l = m + 1;
    }
    return l; //找不到都返回l
}

vector<int> commomValue(vector<int> a, vector<int> b)
{
    vector<int> ret;
    int len = a.size() - 1;
    for(int i = b.size(); i >= 0; --i)
    {
        index = binarySearch(a, len, b[i]);
        if(a[index] == b[i])
            ret.push_back(b[i]);
    }
    return ret;
}

第(3)种方法的实现:

def commomValue(self, a, b):
    m = len(a)
    n = len(b)
    dic = {}
    ret = []
    if(m > n):
        for item in a:
            dic[item] = 1
        for i in range(n):
            if b[i] in dic:
                ret.append(b[i])
    else:
        for item in b:
            dic[item] = 1
        for i in range(m):
            if a[i] in dic:
                ret.append(a[i])
    return ret

第(4)种方法的实现:

vector<int> commomValue(vector<int> a, vector<int> b)
{
    vector<int> ret;
    int m = a.size();
    int n = b.size();
    int i = 0, j = 0;
    while(i < m && j < n)
    {
        if(a[i] == b[j])
        {
            ret.push_back(a[i]);
            ++i;
            ++j;
        }
        else if(a[i] < b[j])
            ++i;
        else
            ++j;
    }
    return ret;
}
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值