首页 > 编程语言 >【教3妹学编程-算法题】使数组变美的最小增量运算数

【教3妹学编程-算法题】使数组变美的最小增量运算数

时间:2023-11-05 10:37:34浏览次数:34  
标签:cnt 下标 值加 nums 编程 美的 cntList 妹学 数组

【教3妹学编程-算法题】使数组变美的最小增量运算数_子数组

2哥 : 3妹,脸上的豆豆好了没呢。
3妹:好啦,现在已经没啦
2哥 : 跟你说很快就会消下去的,还不信~ 既然你的容颜和心情都如此美丽,那我们就再做一道关于美丽的题吧。
3妹:切,2哥就会取笑我,伤心时让我做题,开心时也让我做题!

 1题目: 

给你一个下标从 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

 2思路: 

【教3妹学编程-算法题】使数组变美的最小增量运算数_子串_02

记忆化搜索
把大于 k 的元素视作 k。

由于大于 3 的子数组必然包含等于 3 的子数组,问题转换成:每个长为 3 的子数组都需要包含至少一个 k。
详解如代码中注释:

 3java代码: 


class Solution {
    public int minChanges(String s) {
        // 1、压缩数据,列表每个元素都是连续0或1子串的长度
        List<Integer> cntList = new ArrayList<>();
        char preC = s.charAt(0);
        int cnt = 0;
        for (char c : s.toCharArray()) {
            // 和上一个字符比较,判断是否连续相同
            if (c == preC) {
                cnt++;
            } else {
                // 记录子串长度
                cntList.add(cnt);
                cnt = 1;
            }
            preC = c;
        }
        cntList.add(cnt);


        int minChangeCnt = 0;
        // 2、对压缩列表相邻元素(子串长度)奇偶判断
        for (int i = 0; i < cntList.size(); i++) {
            cnt = cntList.get(i);
            if (cnt % 2 == 0) {
                // 跳过偶数
                continue;
            }
            // 奇数,预取下一个
            int nextCnt = cntList.get(i + 1);
            if (nextCnt % 2 == 1) {
                // 下一个奇数,调整1个。例:{1,3}=>{2,2}
                minChangeCnt++;
                // 已调整,跳过下一个
                i++;
            } else {
                // 下一个是偶数,当前子串调整1个,下一个子串减1
                minChangeCnt++;
                cntList.set(i + 1, nextCnt - 1);
            }
        }
        return minChangeCnt;
    }
}


标签:cnt,下标,值加,nums,编程,美的,cntList,妹学,数组
From: https://blog.51cto.com/u_6813689/8189144

相关文章

  • 有趣的Java之网络多线程——UDP编程
    UDP编程通信基本介绍类DatagramSocket和DatagramPacket【数据包/数据报】实现了基于UDP协议网络程序。UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能安全送到目的地,也不确信什么时候可以抵达。DatagramPacket对象封装了UDP数据报,在数据报中包含了发......
  • 一文读懂ReentrantLock在多线程编程中的作用和优点
    引言在当今这个数字化时代,软件开发已经离不开多线程编程。但是,多线程编程也带来了一系列复杂性和挑战,其中最关键的一个问题就是线程同步和互斥。为了应对这个问题,Java语言提供了一些工具,其中最强大的工具之一就是ReentrantLock。本文将对ReentrantLock进行深入探讨,介绍它在多线程编......
  • JUC并发编程学习笔记(十)线程池(重点)
    线程池(重点)线程池:三大方法、七大参数、四种拒绝策略池化技术程序的运行,本质:占用系统的资源!优化资源的使用!->池化技术(线程池、连接池、对象池......);创建和销毁十分消耗资源池化技术:事先准备好一些资源,有人要用就拿,拿完用完还给我。线程池的好处:1、降低资源消耗2、提高相......
  • 深入研究synchronized:解锁高效多线程编程的秘诀
    大家好,我是老七,点个关注吧,将持续更新更多精彩内容!在Java的多线程编程里,让多个线程能够安全、高效地协同工作是非常重要的。而synchronized这个关键字,就是一个很重要的工具,可以帮助我们实现多线程同步。本文会深入讨论synchronized的作用、使用方法、工作原理,以及它和其他锁机制的比......
  • 《Unix/Linux系统编程》第五章学习笔记
    《Unix/Linux系统编程》第五章学习笔记第五章定时器及时钟服务本章讨论了定时器和定时器服务;介绍了硬件定时器的原理和基于Intelx86的PC中的硬件定时器;讲解了CPU操作和中断处理;描述了Linux中与定时器相关的系统调用、库函数和定时器服务命令;探讨了进程间隔定时器、定......
  • 编程应该拥有诗意
         面向对象的有趣现象编程应该拥有诗意 毕竟是一门高级艺术就应该享受其中有形对象:一切看得见的皆对象无形对象:例如:股票.网络.思想.气候……我们把所有客观世界中的对象,在计算中映射出来,是一件伟大的事情  于是我们开始了愉快的开发体验…我们把应用程序规范......
  • Shell的基本操作和编程入门
    操作:1)给变量赋值,练习echo命令,做下面这个题目:安装中文输入环境:http://rpm.pbone.net  选择第二个,点击右键,复制地址: 按顺序输入下面的命令:     安装完成后,输入zhcon,进入中文输入环境 a)把自己的名字赋值给变量name,把"是"赋值给变量is,把自己的班级名称......
  • JUC并发编程学习笔记(九)阻塞队列
    阻塞队列阻塞队列队列的特性:FIFO(fistinpuptfistoutput)先进先出不得不阻塞的情况什么情况下会使用阻塞队列:多线程并发处理、线程池学会使用队列添加、移除四组API方式抛出异常不抛出异常,有返回值阻塞等待超时等待添加addofferputoffer(Ee,lo......
  • x86平台SIMD编程入门(5):提示与技巧
    1、提示与技巧访问内存的成本非常高,一次缓存未命中可能会耗费100~300个周期。L3缓存加载需要40~50个周期,L2缓存大约需要10个周期,即使L1缓存的访问速度也明显慢于寄存器。所以要尽量保持数据结构对SIMD友好,优先选择std::vector、CAtlArray、eastl::vector等容器,按照顺序读取数据......
  • x86平台SIMD编程入门(4):整型指令
    1、算术指令算术类型函数示例加_mm_add_epi32、_mm256_sub_epi16减_mm_sub_epi32、_mm256_sub_epi16乘_mm_mul_epi32、_mm_mullo_epi32除无水平加/减_mm_hadd_epi16、_mm256_hsub_epi32饱和加/减_mm_adds_epi8、_mm256_subs_epi16最大/最小值_......