leetcode第369周赛

news2025/1/18 10:08:12

2917. 找出数组中的 K-or 值

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

nums 中的 K-or 是一个满足以下条件的非负整数:

  • 只有在 nums 中,至少存在 k 个元素的第 i 位值为 1 ,那么 K-or 中的第 i 位的值才是 1 。

返回 nums 的 K-or 值。

注意 :对于整数 x ,如果 (2^i AND x) == 2^i ,则 x 中的第 i 位值为 1 ,其中 AND 为按位与运算符。

示例 1:

输入:nums = [7,12,9,8,9,15], k = 4
输出:9
解释:nums[0]、nums[2]、nums[4] 和 nums[5] 的第 0 位的值为 1 。
nums[0] 和 nums[5] 的第 1 位的值为 1 。
nums[0]、nums[1] 和 nums[5] 的第 2 位的值为 1 。
nums[1]、nums[2]、nums[3]、nums[4] 和 nums[5] 的第 3 位的值为 1 。
只有第 0 位和第 3 位满足数组中至少存在 k 个元素在对应位上的值为 1 。因此,答案为 2^0 + 2^3 = 9 。

示例 2:

输入:nums = [2,12,1,11,4,5], k = 6
输出:0
解释:因为 k == 6 == nums.length ,所以数组的 6-or 等于其中所有元素按位与运算的结果。因此,答案为 2 AND 12 AND 1 AND 11 AND 4 AND 5 = 0 。

示例 3:

输入:nums = [10,8,5,9,11,6,8], k = 1
输出:15
解释:因为 k == 1 ,数组的 1-or 等于其中所有元素按位或运算的结果。因此,答案为 10 OR 8 OR 5 OR 9 OR 11 OR 6 OR 8 = 15 。

提示:

  • 1 <= nums.length <= 50
  • 0 <= nums[i] < 2^31
  • 1 <= k <= nums.length

思路:

简单题目,直接遍历就好了。

最多只有31位,而且数组长度也才50。重点是 (2^i AND x) == 2^i

两层遍历,外层范围[0-31],内层范围[0-n],n是数组的长度。

ac code:

class Solution {
    public int findKOr(int[] nums, int k) {
        int ans = 0;
            for (int j=0;j<31;j++) {
                int cnt = 0;
                for (int num : nums) {
                    if ((num & (1 << j)) == (1 << j)) {
                    cnt += 1;
                }
                if (cnt >= k) {
                    ans = ans + (1 << j);
                    break;
                }
                }
                
            }
        return ans;
    }
}

2918. 数组的最小相等和

给你两个由正整数和 0 组成的数组 nums1 和 nums2 。

你必须将两个数组中的 所有 0 替换为 严格 正整数,并且满足两个数组中所有元素的和 相等 。

返回 最小 相等和 ,如果无法使两数组相等,则返回 -1 

示例 1:

输入:nums1 = [3,2,0,1,0], nums2 = [6,5,0]
输出:12
解释:可以按下述方式替换数组中的 0 :
- 用 2 和 4 替换 nums1 中的两个 0 。得到 nums1 = [3,2,2,1,4] 。
- 用 1 替换 nums2 中的一个 0 。得到 nums2 = [6,5,1] 。
两个数组的元素和相等,都等于 12 。可以证明这是可以获得的最小相等和。

示例 2:

输入:nums1 = [2,0,2,0], nums2 = [1,4]
输出:-1
解释:无法使两个数组的和相等。

提示:

  • 1 <= nums1.length, nums2.length <= 10^5
  • 0 <= nums1[i], nums2[i] <= 10^6

思路:

直接模拟。答案分几种情况,只要捋清楚即可。

1、nums1不存在0:

  1)nums2不存在0:

       value1(nums1的sum值,同下)!= value2(nums2的sum值,同下)那么就return -1

  2)nums2存在0:

      value1 <= (value2+cnt2(代表nums2种0的个数,同下)):因为0是严格替换成了正整数,那么最小也是1,已经比value1还要大了,再加上正整数,不可能使得value2变小,所以,return -1 ;

     value1 > value 2:因为可以换成任意正整数,所以,value2肯定可以变大成任意值。那么最小的话,肯定就是value1,所以return value1即可。

2、nums1存在0:

  1)nums2 不存在0:

      同理,(value1 + cnt1) >= value2 即可return -1;

      value1 < value2,则 return value2

  2)nums2 存在0:

      因为0最小也是换成1,所以value的范围其实是可以确定的。例如nums1值的范围是[value1 + cnt1(nums1存在0的个数), 正无穷)

      那么nums2也是同理。所以,返回的值取范围交集即可。return Math.max(value1+cnt1, value2+cnt2),为什么是max呢?因为交集!!! 不懂得可以画个图,或者举几个例子。

捋清楚之后,按照分类写清楚就行( 之前没捋清楚还wa了一次。。。)

具体细节,看代码

ac code

class Solution {
    public long minSum(int[] nums1, int[] nums2) {
        long value1 = 0; // nums1的sum
        long value2 = 0;  // nums2的sum
        int cnt1 = 0;  // num1的0的个数
        int cnt2 = 0;   // num2的0的个数
        for (int num : nums1) {
            if (num == 0) {
                cnt1 += 1;
            }
            value1 += num;
        }
        for (int num : nums2) {
            if (num == 0) {
                cnt2 += 1;
            }
            value2 += num;
        }
        // 需要判断value1 如果小于 value2 + cnt2,那么无论如何都不可能
        if (cnt1 == 0 && value1 <= (value2+cnt2)) {
            if (cnt2 == 0 && value1 == value2) {
                return value1;
            } else if (value1 == (value2+cnt2)) {
                return value1;
            }
           return -1;
        }
        if (cnt2 == 0 && value2 <= (value1+cnt1)) {
            if (cnt1 == 0 && value1 == value2) {
                return value1;
            } else if (value2 == (value1+cnt1)) {
                return value2;
            }
            return -1;
        }
        if (cnt1 == 0) {
            return value1;
        }
        if (cnt2 == 0) {
            return value2;
        }
        return Math.max(value1+cnt1, value2+cnt2); 
        
    }
}

2919. 使数组变美的最小增量运算数

给你一个下标从 0 开始、长度为 n 的整数数组 nums ,和一个整数 k 。

你可以执行下述 递增 运算 任意 次(可以是 0 次):

  • 从范围 [0, n - 1] 中选择一个下标 i ,并将 nums[i] 的值加 1 。

如果数组中任何长度 大于或等于 3 的子数组,其 最大 元素都大于或等于 k ,则认为数组是一个 美丽数组 。

以整数形式返回使数组变为 美丽数组 需要执行的 最小 递增运算数。

子数组是数组中的一个连续 非空 元素序列。

示例 1:

输入:nums = [2,3,0,0,2], k = 4
输出:3
解释:可以执行下述递增运算,使 nums 变为美丽数组:
选择下标 i = 1 ,并且将 nums[1] 的值加 1 -> [2,4,0,0,2] 。
选择下标 i = 4 ,并且将 nums[4] 的值加 1 -> [2,4,0,0,3] 。
选择下标 i = 4 ,并且将 nums[4] 的值加 1 -> [2,4,0,0,4] 。
长度大于或等于 3 的子数组为 [2,4,0], [4,0,0], [0,0,4], [2,4,0,0], [4,0,0,4], [2,4,0,0,4] 。
在所有子数组中,最大元素都等于 k = 4 ,所以 nums 现在是美丽数组。
可以证明无法用少于 3 次递增运算使 nums 变为美丽数组。
因此,答案为 3 。

示例 2:

输入:nums = [0,1,3,3], k = 5
输出:2
解释:可以执行下述递增运算,使 nums 变为美丽数组:
选择下标 i = 2 ,并且将 nums[2] 的值加 1 -> [0,1,4,3] 。
选择下标 i = 2 ,并且将 nums[2] 的值加 1 -> [0,1,5,3] 。
长度大于或等于 3 的子数组为 [0,1,5]、[1,5,3]、[0,1,5,3] 。
在所有子数组中,最大元素都等于 k = 5 ,所以 nums 现在是美丽数组。
可以证明无法用少于 2 次递增运算使 nums 变为美丽数组。 
因此,答案为 2 。

示例 3:

输入:nums = [1,1,2], k = 1
输出:0
解释:在这个示例中,只有一个长度大于或等于 3 的子数组 [1,1,2] 。
其最大元素 2 已经大于 k = 1 ,所以无需执行任何增量运算。
因此,答案为 0 。

提示:

  • 3 <= n == nums.length <= 10^5
  • 0 <= nums[i] <= 10^9
  • 0 <= k <= 10^9

思路:

挺有意思的一道题目,算是益智题了。一开始想到的是滑动窗口,最小长度3,然后将窗口内最大值进行增大到k值,后来发现不对,因为窗口内最大值并不一定是最优的,那么就会希望有一个后悔的操作,比如增大了a,但是发现不是最优的,想要增大相邻的b。如何“后悔”增大某个数字?

举个例子:

[43,31,14,4]

73

如果按照原本的想法,增大窗口内最大值,窗口长度是3。那么应该增大43,然后窗口向右滑动后,没有满足条件的k值,则增大31到k值。这样发现,一共花费了30 + 42 = 62。

但是如果我们仅仅只增大31呢? 那么其实就只需要花费42即可。

此时,我们可以考虑下,如果我们选择了43的时候,如果后续需要后悔,那么对于相邻的31是不是需要进行变大操作。

一步步来看:([xxx]表示窗口)

[43,31,14],4

经过操作 假设先按照之前的贪心的想法,先把43进行变动为

[73,31,14],4

此时我们已经花费了30了,如果只是单纯将31 -> 73 是需要42,目前已经花费了30,那么就还需要12,所以,我们可以将31同步转换为61,同理14同步转换为44,即

[73,61,44],4

所以在下一个窗口后那么就是:

73,[61,44,4]

这个时候我们就只需要花费12 就可以满足条件,这样相当于就是执行了后悔的操作。是不是很巧妙的一个办法。

而且,我们还需要注意,窗口尽可能往后取值。

具体实现细节可以看看代码。

ac code

class Solution {
    public long minIncrementOperations(int[] nums, int k) {
        int first = nums[0];
        int second = nums[1];
        int third = nums[2];
        int n = nums.length;
        long ans = 0;
        // 窗口长度为3
        for (int i=3;i<=n;i++) {
            // 如果没有满足条件的值才需要进行变换
            if (first < k && second < k && third < k) {
                // 找到最大值
                int tmp = Math.max(first, Math.max(second, third));
                ans += (k - tmp); // 计算代价
                if (third == tmp) { // 如果是最后一个的话,直接变就行,因为它在窗口待最久
                    third = k;
                } else if (second == tmp) { // 如果是第二个,只需要把后面的加上后悔操作即可,毕竟第一个马上要出窗口了
                    second = k;
                    third += (k - tmp);
                } else { // 同上
                    first = k;
                    second += (k - tmp);
                    third += (k - tmp);
                }
            }
            // 窗口向右滑动
            if (i < n) {
                first = second;
                second = third;
                third = nums[i];
            }
            
        }
        return ans;
    }
}

2920. 收集所有金币可获得的最大积分

节点 0 处现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 。给你一个长度为 n - 1 的二维 整数 数组 edges ,其中 edges[i] = [ai, bi] 表示在树上的节点 ai 和 bi 之间存在一条边。另给你一个下标从 0 开始、长度为 n 的数组 coins 和一个整数 k ,其中 coins[i] 表示节点 i 处的金币数量。

从根节点开始,你必须收集所有金币。要想收集节点上的金币,必须先收集该节点的祖先节点上的金币。

节点 i 上的金币可以用下述方法之一进行收集:

  • 收集所有金币,得到共计 coins[i] - k 点积分。如果 coins[i] - k 是负数,你将会失去 abs(coins[i] - k) 点积分。
  • 收集所有金币,得到共计 floor(coins[i] / 2) 点积分。如果采用这种方法,节点 i 子树中所有节点 j 的金币数 coins[j] 将会减少至 floor(coins[j] / 2) 。

返回收集 所有 树节点的金币之后可以获得的最大积分。

 

示例 1:

输入:edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
输出:11                        
解释:
使用第一种方法收集节点 0 上的所有金币。总积分 = 10 - 5 = 5 。
使用第一种方法收集节点 1 上的所有金币。总积分 = 5 + (10 - 5) = 10 。
使用第二种方法收集节点 2 上的所有金币。所以节点 3 上的金币将会变为 floor(3 / 2) = 1 ,总积分 = 10 + floor(3 / 2) = 11 。
使用第二种方法收集节点 3 上的所有金币。总积分 =  11 + floor(1 / 2) = 11.
可以证明收集所有节点上的金币能获得的最大积分是 11 。 

示例 2:

输入:edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
输出:16
解释:
使用第一种方法收集所有节点上的金币,因此,总积分 = (8 - 0) + (4 - 0) + (4 - 0) = 16 。

 

提示:

  • n == coins.length
  • 2 <= n <= 10^5
  • 0 <= coins[i] <= 10^4
  • edges.length == n - 1
  • 0 <= edges[i][0], edges[i][1] < n
  • 0 <= k <= 10^4

思路:

树上dp,不太会。。。 放下别人的题解。。。

把 floor(coins[i] / 2) 看成右移操作。

一个数最多右移多少次,就变成 000 了?在本题的数据范围下,这至多是 141414 次。

同时,右移操作是可以叠加的,我们可以记录子树中的节点值右移了多少次。

所以可以定义 dfs(i,j)\textit{dfs}(i,j)dfs(i,j) 表示子树 iii 在已经右移 jjj 次的前提下,最多可以得到多少积分。

用「选或不选」来思考,即是否右移:

不右移:答案为 (coins[i]>>j)−k(\textit{coins}[i]>>j)-k(coins[i]>>j)−k 加上每个子树 ch\textit{ch}ch 的 dfs(ch,j)\textit{dfs}(ch,j)dfs(ch,j)。
右移:答案为 coins[i]>>(j+1)\textit{coins}[i]>>(j+1)coins[i]>>(j+1) 加上每个子树 ch\textit{ch}ch 的 dfs(ch,j+1)\textit{dfs}(ch,j+1)dfs(ch,j+1)。
这两种情况取最大值。

作者:灵茶山艾府
 

class Solution {
    public int maximumPoints(int[][] edges, int[] coins, int k) {
        int n = coins.length;
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for (int[] e : edges) {
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        int[][] memo = new int[n][14];
        for (int[] m : memo) {
            Arrays.fill(m, -1); // -1 表示没有计算过
        }
        return dfs(0, 0, -1, memo, g, coins, k);
    }

    private int dfs(int i, int j, int fa, int[][] memo, List<Integer>[] g, int[] coins, int k) {
        if (memo[i][j] != -1) { // 之前计算过
            return memo[i][j];
        }
        int res1 = (coins[i] >> j) - k;
        int res2 = coins[i] >> (j + 1);
        for (int ch : g[i]) {
            if (ch == fa) continue;
            res1 += dfs(ch, j, i, memo, g, coins, k); // 不右移
            if (j < 13) { // j+1 >= 14 相当于 res2 += 0,无需递归
                res2 += dfs(ch, j + 1, i, memo, g, coins, k); // 右移
            }
        }
        return memo[i][j] = Math.max(res1, res2); // 记忆化
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1154029.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

旅行社信息展示服务预约小程序的作用是什么

出行旅游近些年人次非常多&#xff0c;除了自己出行外&#xff0c;旅行社成为众多人的选择&#xff0c;而随着消费者线上信息获取度增加&#xff0c;因此对商家来说也需要线上发展实现赋能。 那么通过【雨科】平台做个旅行社小程序有什么效果呢&#xff1f; 1、品牌宣传、内容…

解决深度学习训练时使用tensorboard http://localhost:6006/无法访问此网站问题

在windows上跑yolov5模型使用了Tensorboard来查看训练过程&#xff0c;开始训练&#xff0c;终端就会提示 直接点击这个网址&#xff0c;就会出现 解决办法是重新开一个终端&#xff0c;激活目前正在使用的虚拟环境&#xff0c;在下面输入 tensorboard --logdir runs\train -…

项目赶工期,如何预防团队成员任务冲突?

项目赶工期时&#xff0c;如果发生任务冲突&#xff0c;往往会直接影响工作进度和效率&#xff0c;可能会导致任务的延误或错失关键节点&#xff0c;进而影响整个项目进度。因此预防团队成员任务冲突对于项目进度至关重要。它可以提高工作效率&#xff0c;保证项目进度&#xf…

Linux中的lrzsz 玩法

一、介绍 lrzsz是一款在Linux里可代替ftp上传和下载的程序&#xff0c;也就是一款软件。它是开发者常用的一款工具&#xff0c;这个工具用于windows机器和远端的Linux机器通过XShell传输文件。 二、lrzsz的安装 在安装之前&#xff0c;我们可以使用下述命令先查看yum仓库中是否…

cad怎么转换成pdf?

cad怎么转换成pdf&#xff1f;cad是什么格式&#xff1f;CAD是计算机辅助设计&#xff08;Computer-Aided Design&#xff09;的缩写&#xff0c;是一种用于制图和设计的软件。CAD软件可以帮助工程师、建筑师、设计师等专业人士创建和编辑各种类型的图形和设计&#xff0c;如平…

行云创新加入深圳市人工智能行业协会

近日&#xff0c;行云创新正式加入深圳市人工智能行业协会。标志着行云创新在人工智能领域的实力和影响力得到了市场更加广泛和深入的认可&#xff0c;展示了行云创新对于深入参与人工智能行业发展&#xff0c;以及与其他领先企业共同推动中国人工智能技术进步的坚定决心。 行…

leetcode:88. 合并两个有序数组(python3解法)

难度&#xff1a;简单 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&am…

HBuilderX实现安卓真机调试

1. 简介 HBuilderX 简称 HX&#xff0c;HBuilder&#xff0c;H 是 HTML 的缩写&#xff0c;Builder 是建设者。是为前端开发者服务的通用 IDE&#xff0c;或者称为编辑器。与 vscode、sublime、webstorm 类似。 它可以开发普通 web 项目&#xff0c;也可以开发 DCloud 出品的 u…

PowerDesigner 16数据库(mysql)逆向生成pdm

1、配置数据源 2、测试数据源 but~~~~没成功&#xff0c;shift

KaiwuDB 亮相第四届跨国公司领导人青岛峰会

10月10日至12日&#xff0c;由商务部和山东省人民政府共同主办的第四届跨国公司领导人青岛峰会在青岛国际会议中心举办。该峰会为跨国公司打造的国家级开放平台&#xff0c;是聚集跨国公司与中国合作、专注跨国公司议题、分享跨国公司经验、链接资源、促进合作的重大活动。Kaiw…

香港高端人才通行证计划学校名单更新扩容184所大全!

香港高端人才通行证计划学校名单更新扩容184所大全&#xff01; 近日香港特首在《施政报告》中宣布&#xff0c;将可以直接申请高端人才通行证计划B、C类的“世界百强名校”名单从176所增加到184所。 因为目前高才通是申请香港身份最快捷的途径&#xff0c;具有申请简单、审批迅…

【C语言】函数指针存疑调试及回调函数编写(结构体内的Callback回调函数传参和虚伪的回调函数__weak声明)

【C语言】函数指针存疑调试及回调函数编写&#xff08;结构体内的Callback回调函数传参和虚伪的回调函数__weak声明&#xff09; 文章目录 函数指针存疑调试函数指针函数调用 回调函数编写结构体内的回调函数虚伪的回调函数 附录&#xff1a;压缩字符串、大小端格式转换压缩字符…

企业3D虚拟展台在线生成工具的功能特点

3D虚拟云展平台提供的上千个素材模版&#xff0c;还有用户编辑和上传的成功案例&#xff0c;此外&#xff0c;三维营销编辑器支持在线选择展台模版、建筑物、产品、特效、动画、图文及视频等&#xff0c;也可以自行上传3D模型/图文视频素材到对应分区&#xff0c;选择自己准备的…

编程实例:操作简单物流快运单据打印软件,可以定制打印格式

编程实例&#xff1a;操作简单物流快运单据打印软件&#xff0c;可以定制打印格式 打印格式可以定制。 编程系统化课程总目录及明细&#xff0c;零基础学编程视频教程&#xff0c;点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.20…

分享大数据分析师前景怎么样? 从事行业有哪些?

数据分析师发展前景和待遇怎么样&#xff1f;有前途吗&#xff1f;好找工作吗&#xff1f;根据某招聘网数据显示&#xff0c;当前市场表现为&#xff1a; 2023年较2022年同期对比增长160%&#xff0c;2022年较2021年下降了46%。 工资待遇&#xff1a;2023年较2022年下降了2…

c++ pcl 选取点云某一点反馈XYZ坐标的代码

看了看以前的代码&#xff0c;有一小段代码很有意思&#xff0c;是关于pcl点云处理的。 如有帮助&#xff0c;点赞收藏关注&#xff01;&#xff01;&#xff01; 读取点云数据&#xff0c;想可视化点云数据&#xff0c;并根据选择&#xff0c;实时显示点云的空间坐标数值。 接…

开放式耳机性价比推荐、最好的开放式耳机推荐

传统入耳式耳机伤听力&#xff0c;长时间佩戴引起耳部不适&#xff0c;甚至会损失听力。为此&#xff0c;市场上出现了佩戴舒适、安全的开放式耳机&#xff0c;而且品牌、型号繁多&#xff0c;质量、性能不一&#xff0c;令人眼花缭乱。我作为第一批接触开放式耳机的首批玩家&a…

Java web(二)MyBatis

文章目录 一、概述1.1 快速入门&#xff08;普通映射方式&#xff09;1.2 IDEA操作MySQL数据库1.3 Mapper代理方式 二、数据库操作【增删改查】2.1 配置文件方式&#xff08;将SQL语句写入配置文件中&#xff09;【完成复杂功能】2.2 注解方式【完成简单功能】 一、概述 MyBat…

近期面试小结

作者&#xff1a;究极逮虾户 最近面试了不少的公司&#xff0c;行情整体来说还是非常差的&#xff0c;如果没有必要不建议大家裸辞&#xff0c;另外就不总结面试的题目了。这次打算着重从项目经验上来给大家讨论下&#xff0c;我觉得这部分可能才是面试中得分比重比较大的部分&…

1-1 prometheus 概述

一、概述 二、特点 三、核心组件 四、基础架构 4.1 Prometheus 的主要模块包含 4.2 运行逻辑 五、Prometheus 与 Zabbix 的对比 六、总结 一、概述 1. 什么是prometheus? 开源系统监控 和 警报工具包受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Br…