算法题解 - 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者组

本文详细解析了牛客编程巅峰赛S1第6场比赛的三道题目,分别涉及大顶堆与哈希集合解决奇数转换问题、排序解决相邻元素最大高度差问题,以及Dijkstra算法求解最短路径问题。通过思路分析和代码实现,深入探讨了每种解法的核心思想和时间空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. 牛牛爱奇数

题目描述

在牛牛面前放着 n 个数,这些数字既有奇数也有偶数,只不过牛牛对奇数情有独钟,他特别想让这些数都变成奇数。

现在牛牛获得了一种能力,他可以执行一种操作:每次选中一个偶数,然后把这些数中与该数相等的数都除以 2,例如现在有一个数组为 [2, 2, 3],那么牛牛可以执行一次操作,使得这个数组变为 [1, 1, 3]。

牛牛现在想知道,对于任意的 n 个数,他最少需要操作多少次,使得这些数都变成奇数?

备注:

1 ≤ n ≤ 10^6,代表一个有多少数字
a1, a2, a3 ... an(1 ≤ ai ≤ 10^9)代表数字的大小

示例1

输入

3,[2,2,3]

输出

1

说明

只需做一次操作,会将其中的偶数2都变成1,满足了所有的数都是奇数的要求。

示例2

输入

3,[1,3,7]

输出

0

说明

不需要做任何操作,因为所有的数原本就是奇数。

解法:大顶堆 + 哈希集合

思路分析

每次可以让所有相同的偶数变成一半,问最少操作次数。

一次操作所有相同数,显然要使用哈希集合进行去重。

而要使得操作次数最少,必然对偶数从大到小进行操作,这样才可以避免对某个偶数进行重复的操作。

想要从大到小操作,显然使用大顶堆保存偶数。每次从堆顶取一个数字进行操作,若得到的新的数字是偶数并且未在哈希集合中出现过,就把它再加入大顶堆中。

时间复杂度:O(max(n, logm))。这里的 m 是最大的偶数。遍历一遍数字需要 O(n),把偶数全变成奇数需要 O(logm)。

空间复杂度:O(n)。

代码实现

public int solve (int n, int[] a) {
   
  Set<Integer> set = new HashSet();
  int ans = 0;
  for(int i: a)
    if((i & 1) == 0) set.add(i);
  Queue<Integer> q = new PriorityQueue<Integer>((x,y) -> y - x);
  q.addAll(set);
  while(!q.isEmpty()) {
   
    int num = q.poll() >> 1;
    ans++
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值