No.0007-CareerCup

Given two object arrays of 'id, weight' (sorted by weight), merge them together and create a one single array. If the 'id's are same, values should be added up and only keep one left. Final result should still be sorted by weight.
有一个对象,含有id和weight两种属性,现在有两个这种对象的数组,分别按照重量排序,要求合并,然后相同的id重量应该加起来只保留一个。要求最后的结果也是按照重量排序的。

1. 询问

id和weight是什么类型?假设id是字符串,weight是整型。
weight有没有可能小于0?假设weight总是大于等于0.
题里的排序是指升序还是降序?假设是升序。
原本的一个数组里面有没有可能存在相同id的两个对象?假设给出的单个数组不会有相同id的对象。

2. 分析

直观解法

这个题让人很容易联想到归并排序,不同的是有两个属性需要考虑,所以多了一步相同id的合并。
就这道题而言,看上去只有两种可能,一个是归并之前合并id,另一个就是归并之后合并id。

归并之前合并id

假如归并之前合并id,先建立以id为键值的哈希表,把一个数组放进去,以index和weight作为value,然后可以遍历另一个数组。只是数组里面的删除并不是那么方便,合并之后的数也只能再另起一个数组然后不断插入。因为删除操作效率太低,考虑置-1,但是插入就没办法回避了。最坏情况时,两个数组都是一样的id,因为插入是O(n),那么整体效率O(n^2),不够高。

归并之后合并id

假设两个数组长度分别为m和n,那么归并就是O(m+n)。然后,还是放进哈希表里面,{id:[index, weight]},遍历数组,假如找到有重复的id,weight相加,留下一个,另一个置-1,复杂度O(m+n)。最后再按照weight排序,把前面-1的部分舍弃即可。这一步O((m+n)log(m+n))。总体时间复杂度O((m+n)log(m+n)),空间复杂度O(m+n)。

3. 代码

class object:
    def __init__(self, id, w):
        self.w = w
        self.id = id
    def __repr__(self):
        return self.id + ":" + str(self.w)


class Solution:
    def mergeObjects(self, l1, l2):
        if not l1 or not l2:
            return l1 or l2
        ret = []
        i = j = 0
        # merge
        while i < len(l1) and j < len(l2):
            if l1[i].w <= l2[j].w:
                ret.append(l1[i])
                i += 1
            else:
                ret.append(l2[j])
                j += 1
        while i < len(l1):
            ret.append(l1[i])
            i += 1
        while j < len(l2):
            ret.append(l2[j])
            j += 1
        # put into dict and handle replicate id
        d = {}
        for i, ob in enumerate(ret):
            if ob.id not in d:
                d[ob.id] = [i, ob.w]
            else:
                prev_idx = d[ob.id][0]
                prev_w = d[ob.id][1]
                ret[prev_idx].w = -1
                ret[i].w += prev_w
                del d[ob.id]
        # sort by weight
        ret.sort(key=lambda x: x.w)
        # remove -1
        return filter(lambda x: x.w != -1, ret)

4. 总结

难度medium。

你可能感兴趣的:(No.0007-CareerCup)