列表

详情


100258. 最高频率的 ID

你需要在一个集合里动态记录 ID 的出现频率。给你两个长度都为 n 的整数数组 nums 和 freq ,nums 中每一个元素表示一个 ID ,对应的 freq 中的元素表示这个 ID 在集合中此次操作后需要增加或者减少的数目。

请你返回一个长度为 n 的数组 ans ,其中 ans[i] 表示第 i 步操作后出现频率最高的 ID 数目 ,如果在某次操作后集合为空,那么 ans[i] 为 0 。

 

示例 1:

输入:nums = [2,3,2,1], freq = [3,2,-3,1]

输出:[3,3,2,2]

解释:

第 0 步操作后,有 3 个 ID 为 2 的元素,所以 ans[0] = 3 。
第 1 步操作后,有 3 个 ID 为 2 的元素和 2 个 ID 为 3 的元素,所以 ans[1] = 3 。
第 2 步操作后,有 2 个 ID 为 3 的元素,所以 ans[2] = 2 。
第 3 步操作后,有 2 个 ID 为 3 的元素和 1 个 ID 为 1 的元素,所以 ans[3] = 2 。

示例 2:

输入:nums = [5,5,3], freq = [2,-2,1]

输出:[2,0,1]

解释:

第 0 步操作后,有 2 个 ID 为 5 的元素,所以 ans[0] = 2 。
第 1 步操作后,集合中没有任何元素,所以 ans[1] = 0 。
第 2 步操作后,有 1 个 ID 为 3 的元素,所以 ans[2] = 1 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<long long> mostFrequentIDs(vector<int>& nums, vector<int>& freq) { } };

golang 解法, 执行用时: 276 ms, 内存消耗: 18.3 MB, 提交时间: 2024-03-24 23:03:22

// https://pkg.go.dev/github.com/emirpasic/gods/v2@v2.0.0-alpha
func mostFrequentIDs(nums, freq []int) []int64 {
	cnt := map[int]int{}
	t := redblacktree.New[int, int]()
	ans := make([]int64, len(nums))
	for i, x := range nums {
		// 减少一次 cnt[x] 的出现次数
		node := t.GetNode(cnt[x])
		if node != nil {
			node.Value--
			if node.Value == 0 {
				t.Remove(node.Key)
			}
		}

		cnt[x] += freq[i]

		// 增加一次 cnt[x] 的出现次数
		node = t.GetNode(cnt[x])
		if node == nil {
			t.Put(cnt[x], 1)
		} else {
			node.Value++
		}
		ans[i] = int64(t.Right().Key)
	}
	return ans
}

golang 解法, 执行用时: 173 ms, 内存消耗: 19 MB, 提交时间: 2024-03-24 23:03:13

func mostFrequentIDs(nums, freq []int) []int64 {
	ans := make([]int64, len(nums))
	cnt := make(map[int]int)
	h := hp{}
	heap.Init(&h)
	for i, x := range nums {
		cnt[x] += freq[i]
		heap.Push(&h, pair{cnt[x], x})
		for h[0].c != cnt[h[0].x] { // 堆顶保存的数据已经发生变化
			heap.Pop(&h) // 删除
		}
		ans[i] = int64(h[0].c)
	}
	return ans
}

type pair struct{ c, x int }
type hp []pair
func (h hp) Len() int           { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].c > h[j].c } // 最大堆
func (h hp) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any)        { *h = append(*h, v.(pair)) }
func (h *hp) Pop() any          { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

java 解法, 执行用时: 169 ms, 内存消耗: 72.7 MB, 提交时间: 2024-03-24 23:02:48

class Solution {
    public long[] mostFrequentIDs(int[] nums, int[] freq) {
        Map<Integer, Long> cnt = new HashMap<>();
        TreeMap<Long, Integer> m = new TreeMap<>();
        int n = nums.length;
        long[] ans = new long[n];
        for (int i = 0; i < n; i++) {
            int x = nums[i];
            if (cnt.containsKey(x) && m.containsKey(cnt.get(x)) && m.merge(cnt.get(x), -1, Integer::sum) == 0) { // --m[cnt[x]] == 0
                m.remove(cnt.get(x));
            }
            long c = cnt.merge(x, (long) freq[i], Long::sum); // cnt[x] += freq[i]
            m.merge(c, 1, Integer::sum); // ++m[cnt[x]]
            ans[i] = m.lastKey();
        }
        return ans;
    }

    public long[] mostFrequentIDs2(int[] nums, int[] freq) {
        int n = nums.length;
        long[] ans = new long[n];
        Map<Integer, Long> cnt = new HashMap<>();
        PriorityQueue<Pair<Long, Integer>> pq = new PriorityQueue<>((a, b) -> Long.compare(b.getKey(), a.getKey()));
        for (int i = 0; i < n; i++) {
            int x = nums[i];
            long c = cnt.merge(x, (long) freq[i], Long::sum);
            pq.add(new Pair<>(c, x));
            while (!pq.peek().getKey().equals(cnt.get(pq.peek().getValue()))) { // 堆顶保存的数据已经发生变化
                pq.poll(); // 删除
            }
            ans[i] = pq.peek().getKey();
        }
        return ans;
    }
}

cpp 解法, 执行用时: 223 ms, 内存消耗: 149.4 MB, 提交时间: 2024-03-24 23:02:24

class Solution {
public:
    vector<long long> mostFrequentIDs(vector<int> &nums, vector<int> &freq) {
        int n = nums.size();
        vector<long long> ans(n);
        unordered_map<int, long long> cnt;
        priority_queue<pair<long long, int>> pq;
        for (int i = 0; i < n; i++) {
            int x = nums[i];
            cnt[x] += freq[i];
            pq.emplace(cnt[x], x);
            while (pq.top().first != cnt[pq.top().second]) { // 堆顶保存的数据已经发生变化
                pq.pop(); // 删除
            }
            ans[i] = pq.top().first;
        }
        return ans;
    }

    vector<long long> mostFrequentIDs2(vector<int> &nums, vector<int> &freq) {
        unordered_map<int, long long> cnt;
        multiset<long long> m;
        int n = nums.size();
        vector<long long> ans(n);
        for (int i = 0; i < n; i++) {
            int x = nums[i];
            auto it = m.find(cnt[x]);
            if (it != m.end()) {
                m.erase(it);
            }
            cnt[x] += freq[i];
            m.insert(cnt[x]);
            ans[i] = *m.rbegin();
        }
        return ans;
    }
};

python3 解法, 执行用时: 849 ms, 内存消耗: 40.4 MB, 提交时间: 2024-03-24 23:01:55

from sortedcontainers import SortedList

class Solution:
    def mostFrequentIDs(self, nums: List[int], freq: List[int]) -> List[int]:
        cnt = Counter()
        sl = SortedList()
        ans = []
        for x, f in zip(nums, freq):
            if cnt[x] in sl:
                sl.remove(cnt[x])  # 多个 cnt[x] 只会移除一个
            cnt[x] += f
            sl.add(cnt[x])
            ans.append(sl[-1])
        return ans

    def mostFrequentIDs2(self, nums: List[int], freq: List[int]) -> List[int]:
        ans = []
        cnt = Counter()
        h = []
        for x, f in zip(nums, freq):
            cnt[x] += f
            heappush(h, (-cnt[x], x))  # 取负号变成最大堆
            while -h[0][0] != cnt[h[0][1]]:  # 堆顶保存的数据已经发生变化
                heappop(h)  # 删除
            ans.append(-h[0][0])
        return ans

上一题