Leetcode6365. 最少翻转操作数题解

题目在此:力扣

 首先,先祝福自己本周周赛过了三题。耶耶耶耶耶耶!虽然第一题因为脑子不好使想了半天,还WA了一次。衷心祈祷今年力扣能上1800分!!!

这道题,我看了一些通过人数,感觉不像是我等凡人能做出来,所以就退缩了。刚才看了题解,有点明白了,在这里记录一下。

1.i能翻转到哪些位置->i的对称点有哪些?

首先,我们考虑这样一个问题:对于数组中的元素i,从左右两个方向考虑,他最远的对称点的下标是什么?

我们先考虑特殊的情况,也是最简单的情况:i作为区间的左右端点,它的对称点分别是什么?

写到这里,我发现,有个ipad也挺好的,我就可以直接在ipad上画完放到博客里,而不用在纸上画完,再在白板上画了,忧桑~

 是不是很简单呢?现在我们算一下复杂的。

如果我们想反转一个数组,就要确认一下i所在区间中左右两个端点最远的下标,现在我们来讨论一下i能对称的最左边的下标:

然后讨论一下i可以对称到的最右边的下标:

那么现在给定一个下标i,我们可以求出通过i可以翻转得到的所有位置的边界了,也就得到了这些位置和i之间的距离的边界,即:

l = max(k - 1 - 2i, -(k-1)), r= min(2n-2i-k-1,k-1)

 求出这个又能怎么样呢?这就意味着对于i,当我们求出l和r这两个边界之后,i+l与i+r之间的值我们都可以翻转得到。

诶,等等,都可以得到吗?我看未必吧。

为什么未必呢,因为i可以与之进行翻转的位置,好像不是完全连续的序列,而是一个公差为2的数列啊?

我们举个例子看看:

 也就是说,i的对称点构成的数列,是一个公差为2的等差数列,则在不同的区间中i的对称点为:

i+l, i+l+2, i+l+4,....,i+r-2,i+r

那既然公差为2,说明奇数和奇数在一个数列中,偶数和偶数在一个数列中,我们就把数组中所有的元素按照奇偶性进行划分好了。

2.怎么求出所有可以访问到的点

我们已经求出了对于某个i所有可以反转到的位置,那么这个i我们怎么得到呢?我们回头再看一下题目:ans[i] 是将 1 放到位置 i 处的 最少 翻转操作次数。

仔细思考一下,从i可以翻转到很多其他的位置,从其他的位置又可以接着翻转,求的又是最少的操作次数,怎么这么像bfs的经典题型啊!

没错,就是bfs。我们把每个可以翻转得到的下标入队,然后枚举队中的每个元素,再看看他们能够翻转的下标。直到队中没有元素了,此时我们已经对所有可以反转的位置都访问过了。

好了,既然如此,上代码吧。

class Solution {
public:
    vector<int> minReverseOperations(int n, int p, vector<int>& banned, int k) {
        vector<int>res(n, -1);
        if(k == 1){  //特殊情况
            res[p] = 0;
            return res;
        }
        unordered_set<int>ban;
        for(int i = 0; i < banned.size(); i++) ban.insert(banned[i]);
        //因为i的对称点是按照公差为2进行枚举的,所以我们按照奇偶性把他们放到不同的集合中
        //用这两个集合枚举我们还没有跳到的位置
        set<int>st[2];
        for(int i = 0; i < n; i++){
            if(i != p && ban.count(i) == 0){
                st[i % 2].insert(i);
            }
        }
        queue<int>q;
        q.push(p);
        res[p] = 0;
        while(q.size()){
            int cur = q.front();
            q.pop();
            int l = max(k - 1 - 2 * cur, -(k - 1));
            int r = min(2 * n - 2 * cur - k - 1, k - 1);
            //判断一下是去奇数还是偶数的集合中查找元素
            int x = (cur + k - 1) % 2;  //观察一下确定奇偶性,cur肯定对应这个点,那么根据这个点的奇偶性就可以判断这个序列的奇偶性
            auto it = (st[x].lower_bound(cur + l)); //找到第一个大于等于cur+l的位置(其实就是这个数列的第一个元素),然后开始枚举后面连续的位置(在已经确定好奇偶性的集合,其实就是连续的奇数或者连续的偶数)
            while(it != st[x].end()){
                //如果遇到了第一个大于cur+r的位置,就停止枚举
                if(*it > cur + r) break;
                //集合中的元素都是没被访问过的,可以从cur一步跳过来
                //更新答案,从集合中去掉已经访问的元素
                res[*it] = res[cur] + 1; 
                q.push(*it);
                it = st[x].erase(it);
            }
        }
        return res;
    }
};

剩下的小细节也在注释中标明了。今天的题解就写到这里,放上我的参考题解:

力扣 LeetCode 灵神的直播讲解,但是我进的迟了,没听。

力扣 好像也是广受好评的大神的题解,我主要看了这个。

就写到这里吧,说好了下午要看看java,结果看了一下午这道题,好想逃避科研,逃避找工作啊!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面试】Java高频面试题(2023最新整理)

文章目录一、java基础1、JDK 和 JRE 有什么区别&#xff1f;2、 和 equals 的区别是什么&#xff1f;3、final 在 java 中有什么作用&#xff1f;4、java 中的 Math.round(-1.5) 等于多少&#xff1f;5、String 属于基础的数据类型吗&#xff1f;6、String str"i"与 …

JUC并发编程高级篇第三章之CAS[Unsafe和原子增强类]

文章目录1、CAS的简介1.1、什么是CAS1.2、使用CAS的前后对比1.3、CAS如何做到不加锁的情况&#xff0c;保证数据的一致性1.4、什么是Unsafe类1.5、CAS方法参数详解1.6、CAS的原理1.7、 CAS的缺点2、原子操作类2.1、基本类型原子类2.2、数据类型原子类2.3、引用类型原子类2.4、对…

66-插入排序

目录 1.直接插入排序 2.折半插入排序 3.在数组arr[l...r]上使用插入排序 类似打扑克牌&#xff0c;整理牌的时候&#xff0c;都是把乱的牌向已经码好的牌中插入——天然的插入排序。 1.直接插入排序 每次选择无序区间的第一个元素&#xff0c;插入到有序区间的合适位置&am…

chatGPT中国入口-ChatGPT评论文章-ChatGPT怎么用

国内怎么玩chatGPT 如果您在国内使用ChatGPT&#xff0c;主要的问题可能是连接OpenAI服务器的速度和稳定性。由于OpenAI位于美国&#xff0c;可能受到中国的网络限制和防火墙的影响&#xff0c;造成访问速度比较慢或不稳定。为了解决这个问题&#xff0c;您可以采取以下方法&a…

idea常用快捷键,包的介绍,访问修饰符

这里有的是我自己定义的快捷键&#xff0c;可以到图片是指定位置查看对应的快捷键是什么。删除当前行&#xff0c;Ctrld复制当前行&#xff0c;自己配置CtrlShift向下箭头补全代码 alt /注释Ctrl /自动导入包在上面位置把两个选项选中&#xff0c;在要导入包的红色位置输入al…

(C++)模板分离编译面对的问题

什么是分离编译模板的分离编译什么是分离编译 一个程序&#xff08;项目&#xff09;由若干个源文件共同实现&#xff0c;而每个源文件单独编译生成目标文件&#xff0c;最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 模板的分离编译 假如有以下…

Spring入门(万字详细附代码讲解)

1.Spring介绍 Spring其实就是一种开源框架,指的是Spring Framework,具有良好的生态,这也是Spring经久不衰的原因 用一句话概括,Spring就是一个集成了众多工具和方法的IOC容器 2.IOC容器 什么是IOC容器呢? IOC的中文翻译过来就是控制反转,IOC容器其实就是控制反转容器 那什…

2022蓝桥杯省赛——卡片

问题描述 小蓝有 k 种卡片, 一个班有 n 位同学, 小蓝给每位同学发了两张卡片, 一位同学的两张卡片可能是同一种, 也可能是不同种, 两张卡片没有顺序。没有两位同学的卡片都是一样的。 给定 n, 请问小蓝的卡片至少有多少种? 输入格式 输入一行包含一个正整数表示 n 。 输出…

Vue中的slot插槽

目录 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 (2)插槽的好处和使用场景 &#xff08;3&#xff09;slot插槽的分类 1、默认插槽 2、具名插槽 3、作用域插槽 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 slot具有“占坑”的作用…

Hadoop MapReduce各阶段执行过程以及Python代码实现简单的WordCount程序

视频资料&#xff1a;黑马程序员大数据Hadoop入门视频教程&#xff0c;适合零基础自学的大数据Hadoop教程 文章目录Map阶段执行过程Reduce阶段执行过程Python代码实现MapReduce的WordCount实例mapper.pyreducer.py在Hadoop HDFS文件系统中运行Map阶段执行过程 把输入目录下文件…

【GoF 23 概念理解】AOP面向切面编程

1. 什么是AOP——面向切面编程 AOP是一种编程范式&#xff0c;提供了一种从宁一个角度来考虑程序结构以完善面向对象编程&#xff08;OOP&#xff09; AOP是一个思想上的变化——主从换位&#xff0c;让原本主动调用的模块变成了被动等待&#xff0c;甚至在毫不知情的情况下被…

CodeTON Round 4 (Div. 1 + Div. 2, Rated, Prizes!)A~E

比赛连接&#xff1a;Dashboard - CodeTON Round 4 (Div. 1 Div. 2, Rated, Prizes!) - Codeforces A. Beautiful Sequence 题意&#xff1a; t(1≤t≤500)组测试每组给定大小为n(1≤n≤100) 的序列&#xff0c;判断它是否存在一个子序列是好序列。一个序列是好序列当且仅当至…

GPT-3:大语言模型小样本学习

论文标题&#xff1a;Language Models are Few-Shot Learners论文链接&#xff1a;https://arxiv.org/abs/2005.14165论文来源&#xff1a;OpenAI一、概述自然语言处理已经从学习特定任务的表示和设计特定任务的架构转变为使用任务无关的预训练和任务无关的架构。这种转变导致了…

Python - Huffman Tree 霍夫曼树实现与应用

目录 一.引言 二.Huffman Tree 理论 1.定义 2.结构 3.构造 三.Huffman Tree 实现 1.生成霍夫曼树 2.编码霍夫曼编码 3.解码霍夫曼编码 4.霍夫曼树编码解码实践 四.总结 一.引言 上篇 Word2vec 的文章中指出每次计算词库 N 个单词的 Softmax 计算量很大&#xff0c;…

办公工具-latex

一、排版总论 1.1 缺省权力 ​ 首先&#xff0c;最重要最需要强调的是&#xff0c;排版是一个信息量极大的工程。字体&#xff0c;格式&#xff0c;对齐方式&#xff0c;页眉页脚&#xff0c;都只是排版的冰山一角&#xff0c;可以说&#xff0c;一个人是没有办法完全控制一个…

JVM 运行时数据区概述及线程

当我们通过前面的&#xff1a;类的加载 --> 验证 --> 准备 --> 解析 --> 初始化&#xff0c;这几个阶段完成后&#xff0c;就会用到执行引擎对我们的类进行使用&#xff0c;同时执行引擎将会使用到我们运行时数据区。 运行时数据区结构 内存概念&#xff1a; 内存…

leetcode:只出现一次的数字 Ⅲ(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; 给你一个整数数组 nums&#xff0c;其中恰好有两个元素只出现一次&#xff0c;其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任…

Qt界面编程(三)—— 父子关系、对象树、信号和槽(自定义信号和槽、Qt5与Qt4的写法)

一、Qt按钮小程序 1. 按钮的创建和父子关系 在Qt程序中&#xff0c;最常用的控件之一就是按钮了&#xff0c;首先我们来看下如何创建一个按钮&#xff1a; #include <QPushButton>QPushButton * btn new QPushButton; //设置父亲btn->setParent(this);//设置文字b…

接口测试-postman使用总结

一、为何使用postman postman是一款简单高效的接口测试工具&#xff0c;能够很方便发送接口请求&#xff0c;易于保存接口请求脚本&#xff0c;postman提供接口响应数据比对功能&#xff0c;可以设置预期结果作断言&#xff0c;还能把测试用例放在一个集合中批量执行&#xff…

【JavaWeb】9—监听器

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…