数组去重,要求O(n)复杂度,传入的数组如下所示,要求去掉重复的id,并且保留最大的w,且不改变原来的顺序。

const union = [
    { id: 1, w: 1 },
    { id: 2, w: 4 },
    { id: 1, w: 2 },
    { id: 2, w: 6 }
]

JavaScript 实现

由于要求 O(n) 复杂度,所以使用了 ES6 Map 对象(类似哈希表),并且是返回新数组而不是修改原数组(删除一个元素就要移动其他元素下标)。现在还存在两个问题:1. 使用 Map 对象无法保证元素的顺序;2. 为了输出一个数组,还得遍历 Map 对象。

function removeDuplicateElements(arr) {
    let map = new Map();
    let res = [];
    for (let i=0; i<arr.length; i++) {
        let cached = map.get(arr[i].id);
        if (!cached || (cached < arr[i].w)) {
            // 如果键值不存在
            // 或者已有的w小于当前遍历的w
            map.set(arr[i].id, arr[i].w);
        }
    }
    for (let [key, value] of map) {
        res.push({
            id: key,
            w: value
        })
    }
    return res
}

Java 实现

本来想用 Java 里面的集合类 LinkedHashMap 解决元素顺序的问题,结果发现 Java 生成一个对象数组的测试用例就很麻烦,折腾了半天,生成测试用例勉强实现了,逻辑代码后面再补上。

package com.company;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class RemoveDuplicateElements {
    public Map<String, Integer> getElement(int id, int w) {
        return Map.of("id",id, "w",w);
    }
    public List<Map<String, Integer>> getTestCase() {
        List<Map<String, Integer>> list = new ArrayList<>();
        int[] idList = {1,2,1,2}, wList = {1,4,2,6};
         for (int i=0; i<4; i++) {
            list.add(getElement(idList[i], wList[i]));
        }
        return list;
    }
    public static void main(String[] args) {
        RemoveDuplicateElements removeDuplicateElements = new RemoveDuplicateElements();
        List<Map<String, Integer>> testCase = removeDuplicateElements.getTestCase();
        System.out.println(testCase);
    }
}

一杯绿茶
199 声望17 粉丝

人在一起就是过节,心在一起就是团圆