leetcode每日一题:最少翻转操作数

news/2025/3/20 12:35:40/文章来源:https://www.cnblogs.com/podongfeng/p/18782817

image

题目

2612. 最少翻转操作数

给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p ,它们表示一个长度为 n 且下标从 0 开始的数组 arr ,数组中除了下标为 p 处是 1 以外,其他所有数都是 0

同时给你一个整数数组 banned ,它包含数组中的一些位置。banned 中第 i 个位置表示 arr[banned[i]] = 0 ,题目保证 banned[i] != p

你可以对 arr 进行 若干次 操作。一次操作中,你选择大小为 k 的一个 子数组 ,并将它 翻转 。在任何一次翻转操作后,你都需要确保 arr 中唯一的 1 不会到达任何 banned 中的位置。换句话说,arr[banned[i]] 始终 保持 0

请你返回一个数组 ans ,对于 [0, n - 1] 之间的任意下标 ians[i] 是将 1 放到位置 i 处的 最少 翻转操作次数,如果无法放到位置 i 处,此数为 -1

  • 子数组 指的是一个数组里一段连续 非空 的元素序列。
  • 对于所有的 ians[i] 相互之间独立计算。
  • 将一个数组中的元素 翻转 指的是将数组中的值变成 相反顺序

示例 1:

输入:n = 4, p = 0, banned = [1,2], k = 4
输出:[0,-1,-1,1]
解释:k = 4,所以只有一种可行的翻转操作,就是将整个数组翻转。一开始 1 在位置 0 处,所以将它翻转到位置 0 处需要的操作数为 0 。
我们不能将 1 翻转到 banned 中的位置,所以位置 1 和 2 处的答案都是 -1 。
通过一次翻转操作,可以将 1 放到位置 3 处,所以位置 3 的答案是 1 。

示例 2:

输入:n = 5, p = 0, banned = [2,4], k = 3
输出:[0,-1,-1,-1,-1]
解释:这个例子中 1 一开始在位置 0 处,所以此下标的答案为 0 。
翻转的子数组长度为 k = 3 ,1 此时在位置 0 处,所以我们可以翻转子数组 [0, 2],但翻转后的下标 2 在 banned 中,所以不能执行此操作。
由于 1 没法离开位置 0 ,所以其他位置的答案都是 -1 。

示例 3:

输入:n = 4, p = 2, banned = [0,1,3], k = 1
输出:[-1,-1,0,-1]
解释:这个例子中,我们只能对长度为 1 的子数组执行翻转操作,所以 1 无法离开初始位置。

提示:

  • 1 <= n <= 105
  • 0 <= p <= n - 1
  • 0 <= banned.length <= n - 1
  • 0 <= banned[i] <= n - 1
  • 1 <= k <= n
  • banned[i] != p
  • banned 中的值 互不相同

思路

​ 先读懂题目,题目比较长,这里翻转的意思,就是倒序。初始情况下,数组中只有1个值是1。我们先看下下标p为1,经过1次翻转,可能到达哪些位置:

  • 如果p作为子数组的右侧端点,那么翻转后,可以达到最小值 : p - k + 1
  • 如果p作为子数组的左侧端点,那么翻转后,可以达到最大值 : p + k - 1

​ 当然,上述只是最理想的情况,由于我们子数组的长度固定为k,所以当前节点p可能无法作为子数组的左侧端点或者右侧端点,否则就会越界,对于这2种情况,我们再次分类讨论:

  • 如果 p < k - 1,此时p无法作为子数组右侧端点,可以让p移动到最左侧的子数组是[0, k-1] ,此时p移动到的位置是 k - 1 - p
  • 如果 p > n - k,此时p无法作为子数组的左侧端点,可以让p移动到最右侧的子数组是[n-k, n-1],此时p移动到的位置是 2 * n - p - 1 - k

​ 这样,我们已经获取了p经过1次翻转后,可能到达的位置范围,不过这里需要注意的是,并不是范围内每个位置都可以达到,实际上,当我们用滑动窗口滑动子数组的时候,每滑动1个位置,p的翻转位置其实移动了2。

​ 另外,我们还要去掉被ban的位置,这些位置永远不可达。

​ 那我们知道了经过1次移动,可以达到的全部位置后,我们可以使用BFS的思路,继续对上一次达到的新位置去继续遍历。注意,这里只要每次遍历新达到的位置即可,之前已经达到过的位置,既是再次达到,可以确定之前已经使用更少的翻转次数达到过。

图解

image

代码

image

优化

​ 我们在过了给出的示例提交后,发现TLE了。

image

​ 仔细分析一下,问题的原因是,我们每次遍历的时候,都是在[min, max]之间间隔2每次遍历全部的位置,如果k比较大,这中间位置很多,但是被ban掉的位置和之前已经达到过的位置,是不需要再次遍历的,虽然我们这里使用continue跳过了,但是还是有很大的浪费,最好可以只精确遍历未达到过的位置。

​ 由于每一次[min, max]之间达到的位置内部,奇偶性都是一致的(2次[min, max]之间奇偶性可能不同),所以,我们可以把未达到过的位置,区分奇偶性放在2个TreeSet中,然后从TreeSet中获取到[min, max]的可能值。

优化后代码

image

public int[] minReverseOperations(int n, int p, int[] banned, int k) {Set<Integer> banSet = new HashSet<>();for (int ban : banned) {banSet.add(ban);}// 未决策的位置,分开奇偶,因为每次广度优先遍历,要么全是奇数、要么全是偶数TreeSet[] oddEvenArr = new TreeSet[]{new TreeSet<Integer>(), new TreeSet<Integer>()};for (int i = 0 ; i < n; i++) {if (banSet.contains(i) || i == p) {continue;}oddEvenArr[i&1].add(i);}int[] ans = new int[n];Arrays.fill(ans, -1);ans[p] = 0;Queue<Integer> queue = new LinkedList<>();queue.add(p);while (!queue.isEmpty()) {int cur = queue.poll();int min, max;if (cur < k - 1) {min = k - 1 - cur;} else {min = cur - k + 1;}if (cur > n - k) {max = 2 * n - k - 1 - cur;} else {max = cur + k - 1;}TreeSet<Integer> set = oddEvenArr[min&1];Iterator<Integer> it = set.tailSet(min).iterator();while (it.hasNext()) {int val = it.next();if (val > max) {break;}ans[val] = ans[cur] + 1;queue.add(val);it.remove();}}return ans;
}

耗时

image

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黄色网站破解

最近再查资料, 莫名其妙弹窗黄色网站下载页面, 我的手机是iOS非越狱版本, 我当然是敢点击的, 即使有病毒也不怕。 51duhui是虚假的应用, 假冒app store风格下载安装, 狗日的,发现是下载mobileconfig, 看下下载的按钮,代码如下:function jumpurl(url) {setTimeout(f…

“人工智能+”智赋千行百业!

今年,DeepSeek在AI赛道一骑绝尘 以“火炎焱燚”之势迅速延伸 开启中国AI黄金时代 如今,中国的AI故事正在书写新篇 中国的科技强国之路也正越走越宽在DeepSeek引领的人工智能热潮中 作为云服务国家队 天翼云“息壤”智算平台率先完成 国产算力与DeepSeek-R1/V3 系列大模型的深…

使用Kettle将sqlserver库表结构和数据导入到oracle

一、官网下载kettle的压缩包pdi-ce-9.4.0.0-343.zip ,下载jtds-1.3.1.jar和ojdbc8-19.3.0.0.jar 将jar放入\data-integration\lib 目录下二、将zip解压后,是一个data-integration文件夹,找到spoon.bat 双击运行,即可打开kettle工具三、打开以后,右键点击转换,新建一个转换…

Windows 11 24H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 3 月更新)

Windows 11 24H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 3 月更新)Windows 11 24H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 3 月更新) Windows 11, version 24H2 Enterprise Arm64 x64 (updated Mar 2025) 请访问原文链接:https://sysin.org/blog/windows-11/ 查看最…

作业三

问题 内容这个作业属于哪个课程 课程链接这个作业要求在哪里 作业要求这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序姓名 学号何松 3123004786洪徐博 3123004747PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)Planning 计划 Esti…

VMware Live Site Recovery 9.0.2.2 发布 - 数据中心灾难恢复 (DR)

VMware Live Site Recovery 9.0.2.2 发布 - 数据中心灾难恢复 (DR)VMware Live Site Recovery 9.0.2.2 发布 - 数据中心灾难恢复 (DR) Site Recovery Manager 9.0 Update 2 请访问原文链接:https://sysin.org/blog/vmware-live-site-recovery-9/ 查看最新版。原创作品,转载请…

可视化图解算法: 两个链表的第一个公共节点

对于链表的相关操作,我们总结了一套【可视化+图解】方法,依据此方法来解决链表相关问题,链表操作变得易于理解,写出来的代码可读性高也不容易出错。1. 题目 描述 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,…

Windows 10 on ARM, version 22H2 ARM64 中文版、英文版下载 (2025 年 3 月更新)

Windows 10 on ARM, version 22H2 ARM64 中文版、英文版下载 (2025 年 3 月更新)Windows 10 on ARM, version 22H2 ARM64 中文版、英文版下载 (2025 年 3 月更新) Windows 10 on ARM, version 22H2 ARM64 (updated Mar 2025) 请访问原文链接:https://sysin.org/blog/windows-1…

河南郑州亚克力代加工厂家资源-代加工-外协加工-委外加工-激光代加工-河南郑州亚克力切割雕刻代加工-芯晨微纳(河南)

在河南省寻找亚克力代加工厂家,可以通过以下渠道和注意事项进行筛选: 一、推荐查找渠道**B2B平台 -百度搜索“河南郑州亚克力代加工厂家”、“激光代加工”、“亚克力加工”等关键词阿里巴巴:搜索“河南亚克力加工”“亚克力定制”等关键词,筛选河南本地厂家(如郑州、洛阳…

PureBasic 6.20 (macOS, Linux, Windows) - 现代的 BASIC 编程语言及 IDE

PureBasic 6.20 (macOS, Linux, Windows) - 现代的 BASIC 编程语言及 IDEPureBasic 6.20 (macOS, Linux, Windows) - 现代的 BASIC 编程语言及 IDE PureBasic is a modern BASIC programming language. 请访问原文链接:https://sysin.org/blog/purebasic/ 查看最新版。原创作品…

GIMP 3.0.0 (Linux, macOS, Windows) 正式版发布 - 免费开源图像编辑器

GIMP 3.0.0 (Linux, macOS, Windows) 正式版发布 - 免费开源图像编辑器GIMP 3.0.0 (Linux, macOS, Windows) 正式版发布 - 免费开源图像编辑器 GNU Image Manipulation Program (GIMP) 请访问原文链接:https://sysin.org/blog/gimp/ 查看最新版。原创作品,转载请保留出处。 作…

WinSCP主机名

连接Wifi的情况下,Ubuntu命令行输入"ifconfig",如图即为主机名当我在使用网线时,打开虚拟机显示的ifconfig却是这样:此时连接WinSCP是行不通的因此只能拔掉网线,在WiFi情况下,重启虚拟机,命令行如下: sudo shutdown -r now 然后再重新接入WinSCP即可。 只要在…