算法学习——LeetCode力扣贪心篇4

news2024/11/27 13:44:37

算法学习——LeetCode力扣贪心篇4

在这里插入图片描述

763. 划分字母区间

763. 划分字母区间 - 力扣(LeetCode)

描述

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

示例

示例 1:
输入:s = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、“defegde”、“hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。

示例 2:

输入:s = “eccbbbbdec”
输出:[10]

提示

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成
代码解析

题意简述为
即最多能切多少段?使得同一字母都出现在一个片段,且片段最多。

思路
先统计整个字符串的map字典。
然后再次遍历字符串,当遍历字符串某一点时,当前字符串区间出现的字母个数就是整个字符串的字母个数(即当前字符串区间出现的字母,全部都出现在这里,区间外没有这个字母再次出现了),纪录当前区间是一段。

class Solution {
public:
    vector<int> partitionLabels(string s) {
        
        map<char,int> my_map; //整个字符串字典
        map<char,int> my_map_tmp;// 一段的字典
        vector<int> result;
        int start = 0; //段开始标志
        for(int i=0 ; i< s.size() ; i++) my_map[s[i]]++;

        // for(auto it:my_map) cout<<it.first<<' '<<it.second<<endl;

        for(int i=0 ; i<s.size() ;i++)
        {
            my_map_tmp[s[i]]++; //更新一段的字典
            //检查当前的字典和全局字典,字母出现的次数
            for(auto it = my_map_tmp.begin() ; it != my_map_tmp.end() ;it++)
            {
            	//当前段中字母出现个数和全局不同(即还有字母没发现),跳出
                if( it->second != my_map[it->first]) break;
                //当前段出现的字母,字母数量和全局数量都相同(即全发现)
                if(it == -- my_map_tmp.end() ) //遍历到最后一个字母都没跳出
                {
                    result.push_back(i-start+1); //记录段长度
                    start = i+1; //下一段开始点
                    my_map_tmp.clear();//清空段字典
                }
            }
        }
        
        return result;
    }
};

56. 合并区间

56. 合并区间 - 力扣(LeetCode)

描述

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

代码解析

按照左边界排序,排序之后局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间了,整体最优:合并所有重叠的区间。

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

class Solution {
public:
    static bool compare(vector<int>&a , vector<int>&b)
    {
        return a[0] < b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        
        if(intervals.size() <= 1) return intervals;
        vector<vector<int>> result;
        //按照区间左边界排序
        sort(intervals.begin() , intervals.end(),compare);
        //第一个区间作为临时区间
        vector<int> tmp = intervals[0];

        for(int i = 1 ; i< intervals.size() ; i++)
        {
        	//如果当前区间和临时区间有重叠
        	//取临时区间和当前区间的公共集合作为新的临时区间
            if(tmp[1] >= intervals[i][0])
            {
                tmp[0] = min(tmp[0] , intervals[i][0]);
                tmp[1] = max(tmp[1] , intervals[i][1]);
            }
            else//当临时区间和当前区间不重合
            {
                result.push_back(tmp);//临时区间存入
                tmp = intervals[i];//当前区间为新的临时区间
            }
            if(i==intervals.size()-1)//当前区间是最后一个区间的时候
            {
                 result.push_back(tmp);//存入未存入的临时区间
            }
        }
        return result;
    }
};

738. 单调递增的数字

738. 单调递增的数字 - 力扣(LeetCode)

描述

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

示例

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

提示

  • 0 <= n <= 109

代码解析

找到一个比目标值小的最大递增数列

递归法

从左到右遍历,找符合递增的部分,
当发现不符合的部分,不符合部分都置9
找到符合部分-1的最大递增数(后面都置9要借位)

例:输入668841
发现6688部分符合递增,但是从4开始不符合,因此41变成99
之后找到6688-1的最大递增(后面99要借1)为6679
在和最后两个99合并,得到667999

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        
        if(n<10) return n;
        string num = to_string(n);
        string result ;
        result += num[0];
        int flag = 0; //是否符合标志位,当不符合递增的时候,后面都置9
        for(int i=1 ;i<num.size();i++) //遍历
        {
            if(num[i] >= num[i-1] && flag==0) //找到符合递增的部分
            {
                result += num[i];
            }
            else if(flag==0) //找到第一个不符合递增的数 ,并求之前符合部分-1最大递增
            {
                result = to_string(monotoneIncreasingDigits(stoi(result)-1) );
                flag = 1; //设置为不符合
            }

            if(flag == 1) //不符合后面全都置9
            {
                 result += '9';
            }
        }

        return stoi(result);
    }
};

贪心法 反向遍历

局部最优:遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。

全局最优:得到小于等于N的最大单调递增的整数。

但这里局部最优推出全局最优,还需要其他条件,即遍历顺序,和标记从哪一位开始统一改成9。

那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        
        if(n<10) return n;
        string num = to_string(n);
        int flag;
      
        for(int i=num.size()-1 ; i >=1 ;i--)
        {
           if(num[i] < num[i-1])
           {
               flag = i;
               num[i-1] -= 1;
           }
        }

        for(int i = flag ; i<num.size() ;i++)
        {
            num[i] = '9';
        }

        return stoi(num);
    }
};

968. 监控二叉树

968. 监控二叉树 - 力扣(LeetCode)

描述

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

示例

示例 1:

在这里插入图片描述

输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。

示例 2:

在这里插入图片描述

输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。

提示

  • 给定树的节点数的范围是 [1, 1000]。
  • 每个节点的值都是 0。

代码解析

从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
此时,大体思路就是从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。

我们分别有三个数字来表示:

0:该节点无覆盖
1:本节点有摄像头
2:本节点有覆盖

  • 情况1:左右节点都有覆盖
    左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。
    在这里插入图片描述

  • 情况2:左右节点至少有一个无覆盖的情况
    如果是以下情况,则中间节点(父节点)应该放摄像头:

在这里插入图片描述

  • 情况3:左右节点至少有一个有摄像头
    如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)
  • 情况4:头结点没有覆盖
    以上都处理完了,递归结束之后,可能头结点 还有一个无覆盖的情况,如图:

在这里插入图片描述

class Solution {
private:
    int result;
    int traversal(TreeNode* cur) {

        // 空节点,该节点有覆盖
        if (cur == NULL) return 2;

        int left = traversal(cur->left);    // 左
        int right = traversal(cur->right);  // 右

        // 情况1
        // 左右节点都有覆盖
        if (left == 2 && right == 2) return 0;

        // 情况2
        // left == 0 && right == 0 左右节点无覆盖
        // left == 1 && right == 0 左节点有摄像头,右节点无覆盖
        // left == 0 && right == 1 左节点有无覆盖,右节点摄像头
        // left == 0 && right == 2 左节点无覆盖,右节点覆盖
        // left == 2 && right == 0 左节点覆盖,右节点无覆盖
        if (left == 0 || right == 0) {
            result++;
            return 1;
        }

        // 情况3
        // left == 1 && right == 2 左节点有摄像头,右节点有覆盖
        // left == 2 && right == 1 左节点有覆盖,右节点有摄像头
        // left == 1 && right == 1 左右节点都有摄像头
        // 其他情况前段代码均已覆盖
        if (left == 1 || right == 1) return 2;

        // 以上代码我没有使用else,主要是为了把各个分支条件展现出来,这样代码有助于读者理解
        // 这个 return -1 逻辑不会走到这里。
        return -1;
    }

public:
    int minCameraCover(TreeNode* root) {
        result = 0;
        // 情况4
        if (traversal(root) == 0) { // root 无覆盖
            result++;
        }
        return result;
    }
};

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

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

相关文章

第13集《佛说四十二章经》

和尚尼慈悲&#xff01;诸位法师、诸位居士&#xff0c;阿弥陀佛&#xff01; 请大家打开讲义第十八面&#xff0c;第三十六章、辗转获胜。 佛陀在《法华经》上&#xff0c;对我们的三界果报&#xff0c;清楚的开示说&#xff1a;三界无安&#xff0c;犹如火宅&#xff0c;众…

地理信息数据要素价值

文章目录 前言一、地理信息数据成为生产要素的重要内涵二、推动地理信息数据要素价值实现的重点及方式(一)公共地理信息数据(二)企业地理信息数据前言 面对数字经济发展新形势新需求,我们将统筹发展与安全,推动数据资源向数据资产转变,发挥时空数据作为新型生产要素价值…

Windows 系统盘(C盘)爆红如何清理、如何增加C盘空间

1、简介 Windows系统中&#xff0c;系统和保留占用太多的空间&#xff0c;一旦系统盘分配空间较少&#xff0c;使用一段时间后&#xff0c;备份文件、临时文件、系统更新记录等都会在占用系统盘较大空间&#xff0c;导致系统盘空间不够使用&#xff0c;会造成应用运行卡顿。如何…

uniapp 开发一个密码管理app

密码管理app 介绍 最近发现自己的账号密码真的是太多了&#xff0c;各种网站&#xff0c;系统&#xff0c;公司内网的&#xff0c;很多站点在登陆的时候都要重新设置密码或者通过短信或者邮箱重新设置密码&#xff0c;真的很麻烦 所以准备开发一个app用来记录这些站好和密码…

每日一题——LeetCode1436.旅行终点站

方法一 个人方法 两次遍历set 终点站不通往其他任何城市&#xff0c;那么终点站只会出现在[cityA,cityB]的第二位&#xff0c;利用set第一次遍历保存所有站点&#xff0c;第二次遍历去除所有在第一位出现的站点&#xff0c;剩下的站点就是不通往任何站点的终点站&#xff1a; …

Java中的String类的常用方法(对于字符串的常用操作)

目录 一、获取指定索引的字符 二、 获取指定字符或者字符串的索引位置 三、判断字符串是否以指定内容开头或结尾 四、替换指定的字符或者是字符串 五、获取字符串的子串 六、将字符串转换为字符数组 七、比较字符串的内容是否相等 八、连接字符串 九、比较两个字符串的大…

[CTF]-PWN:C++文件更换libc方法(WSL)

C文件与C文件更换libc有很多不一样的地方&#xff0c;我是在写buu的ciscn_2019_final_3才意识到这个问题&#xff0c;C文件只需要更换libc和ld就可以了&#xff0c;但是C文件不同&#xff0c;除了更换libc和ld&#xff0c;它还需要更换libstdc.so.6和libgcc_s.so.1 更换libc和…

指针习题回顾(C语言)

目录 数组指针和指针数组 编程题&#xff1a; 字符串逆序 字符串左旋 题目1概述&#xff1a; 代码实现&#xff1a; 题目2概述&#xff1a; 代码实现&#xff1a; 调整奇偶顺序 题目概述&#xff1a; 代码实现&#xff1a; 冒泡排序 二级指针 代码解读&#xff1a; …

力扣---通配符匹配

题目描述&#xff1a; 给你一个输入字符串 (s) 和一个字符模式 (p) &#xff0c;请你实现一个支持 ? 和 * 匹配规则的通配符匹配&#xff1a; ? 可以匹配任何单个字符。 * 可以匹配任意字符序列&#xff08;包括空字符序列&#xff09;。 判定匹配成功的充要条件是&#xff…

lazarus:LCL 嵌入 fpwebview 组件,做一个简单浏览器

从 https://github.com/PierceNg/fpwebview 下载 fpwebview-master.zip 简单易用。 先请看 \fpwebview-master\README.md cd \lazarus\projects\fpwebview-master\demo\lclembed 修改 lclembed.lpr 如下&#xff0c;将 fphttpapp. 注释掉&#xff0c;因为我用不上。 progr…

【STM32 CubeMX】I2C层次结构、I2C协议

文章目录 前言一、I2C的结构层次1.1 怎样在两个设备之间传输数据1.2 I2C如何传输数据1.3 硬件框图1.4 软件层次 二、IIC协议2.1 硬件连接2.2 I2C 总线的概念2.3 传输数据类比2.3 I2C信号2.4 I2C数据的含义 总结 前言 在STM32 CubeMX环境中&#xff0c;I2C&#xff08;Inter-In…

相机图像质量研究(24)常见问题总结:CMOS期间对成像的影响--摩尔纹

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

红队学习笔记Day5 --->总结

今天先不讲新知识&#xff0c;来小小的复习一下 1.8888&#xff1f;隧道端口你怎么回事 在做隧道和端口转发的时候&#xff0c;我们常见的是通过一台跳板机&#xff0c;让外网的机器去远程连接到内网的一些机器&#xff0c;这时候就常见一些这样的命令 以防忘了&#xff0c;先…

面试突击1

1.当线程没有拿到资源时&#xff0c;用户态和内核态的一个切换 在操作系统中&#xff0c;进程和线程是执行程序的基本单位。为了管理这些单位&#xff0c;操作系统使用了一种称为“进程状态”的机制&#xff0c;其中包括用户态和内核态两种状态。这两种状态代表了进程或线程在…

ubuntu屏幕小的解决办法

1. 安装vmware tools , 再点自适应客户机 执行里面的vmware-install.pl这个文件 &#xff1a;sudo ./vmware-install.pl 执行不了可以放到家目录&#xff0c;我放在了/home/book 里面 最后点这个自适应客户机 然后我这里点不了是因为我点了控制台视图和拉伸客户机&#xff0c…

[word] word怎么取消隐藏文字 #职场发展#微信

word怎么取消隐藏文字 Word有很多实用的技巧&#xff0c;学会了可以节省大量的时间在编辑上。今天就给大家分享下word怎么取消隐藏文字这个小技能。 1.选中内容设置 首先先显示段落符号标记(快捷鍵Ctrl Shift8)&#xff0c;之后选中文本内容。 2.设置取消隐藏的文字 点击开始…

unreal engine5.1中设置convex decomposition凸包分解

UE5系列文章目录 文章目录 UE5系列文章目录前言一、convex decomposition是什么&#xff1f;二、convex decomposition属性设置 前言 今天使用ue5根据网上教程制作可操控直升机&#xff0c;找属性convex decomposition凸包分解&#xff0c;默认的碰撞如下图 如果想使用精细化…

回溯题中借助哈希法来巧妙去重的操作

今天总结一下回溯法以来做过的这些题&#xff0c;我又发现一个困扰了我的问题&#xff0c;就是在491. 非递减子序列、46. 全排列、47. 全排列 II中都有涉及到用哈希法&#xff0c;去记录曾经用过的元素&#xff0c;下面来总结一下吧。 首先得知道&#xff0c;为什么会用到哈希法…

OpenAI 最新发布的从文本生成视频模型 Sora 炸裂登场,它能根据文字指令创造逼真且富有想象力的场景

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 此页面上的所有视频均由 Sora 直接生成&#xff0c;未经修改。 OpenAI - Sora is an AI model that can create realistic and imaginative scenes f…

poetry,一个好用的Python项目依赖管理库

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️付费专栏:Python专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前言 在 Python 开发领域,项目依赖管理是一个至关重要的问题。Python Poetry 是一个现代化的项目依赖管理工具,旨在简化 Python 项目的依赖管理和打包…