C++基础算法离散化及区间合并篇

📟作者主页:慢热的陕西人

🌴专栏链接:C++算法

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

主要讲解了双指针,位运算,离散化以及区间合并。

在这里插入图片描述

文章目录

    • Ⅴ. 双指针
    • Ⅵ. 位运算
    • Ⅶ.离散化:
    • Ⅶ. 区间合并

Ⅴ. 双指针

是一种利用单调规律将二重循环的时间复杂度降为O(N)的算法;

例如:剑指 Offer 48. 最长不含重复字符的子字符串 - 力扣(LeetCode)

如果我们用暴力算法的话,肯定是需要O(N)的复杂度,但是我们采用双指针方式可以实现在O(N)的时间复杂度实现

代码:

    int lengthOfLongestSubstring(string s) {int map[257] = { 0 };int res = 0;for(int i = 0; i < s.size(); ++i){map[s[i]]++;while(map[s[i]] > 1){map[s[j]]--;++j;}res = max(res, i - j + 1);}return res;}

Ⅵ. 位运算

位运算通常是利用二进制的一些性质展开的

例如:剑指 Offer 15. 二进制中1的个数 - 力扣(LeetCode)

class Solution {
public:uint32_t lowbit(uint32_t x){return (x & ~x + 1);}int hammingWeight(uint32_t n) {int sum = 0;while(lowbit(n)) n &= ~lowbit(n), sum++;return sum;}
};

其中lowbit(n)函数返回的是n的第一个1的数字:例如5(101),他就返回1;

Ⅶ.离散化:

离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小

有时候我们的数据范围是(0 , 10e9),但是数据的总数却可能只有(0, 10e5), 这时候我们没必要去开10e9的空间,只需要开最大10e5的空间所要离散化的数据映射到这个小空间里;

例如;{1000, 1111, 1200, 1100, 1250}

我们映射下来
[ 1000 − > 1 ] , [ 1100 − > 2 ] , [ 1111 − > 3 ] , [ 1200 − > 4 ] , [ 1250 − > 5 ] [1000->1],[1100->2],[1111->3],[1200->4],[1250->5] [1000>1],[1100>2],[1111>3],[1200>4],[1250>5]
所以我们要实现离散化需要做非常重要的两步:

①如何将离散化后的数据进行去重;

②如何计算出数据离散化后对应的值;

代码如下:

vector<int> alls;//存储待离散化的数据
sort(alls.begin(), alls.end());//排序
alls.erase(unique(alls.begin(), alls.end()), alls.end()); //①对排列好的数据进行去重//②计算出数据离散化后对应的值
int find(int x)
{int l = 0; r = alls.size() - 1;while(l < r){int mid = (l + r) >> 1;if(alls[mid] >= x) r = mid;else l = mid + 1;}return r + 1;//根据题意
}

例题:

在这里插入图片描述

测试数据:

//输入
3 3
1 2
3 6
7 5
1 3
4 6
7 8
//输出
8
0
5

代码:

#include<iostream>
#include<vector>
#include<algorithm>#define N 300010
using namespace std;typedef pair<int, int> PII;int a[N], s[N];vector<int> alls;
vector<PII> add, query;int n, m;//n次操作, m个区间int find(int x)
{int l = 0, r = alls.size() - 1;while (l < r){int mid = l + r >> 1;if (alls[mid] >= x) r = mid;else l = mid + 1;}return r + 1;
}
int main()
{cin >> n >>m;for (int i = 1; i <= n; ++i){int x, c;cin >> x >> c;add.push_back({x, c});alls.push_back(x);}for (int i = 1; i <= m; ++i){int l, r;cin >> l >> r;query.push_back({ l, r });alls.push_back(l);alls.push_back(r);}//去重操作sort(alls.begin(), alls.end());alls.erase(unique(alls.begin(), alls.end()), alls.end());//处理加数for (auto item : add){int pot = find(item.first);a[pot] += item.second;}//计算前缀和for (int i = 1; i <= alls.size(); ++i) s[i] = s[i - 1] + a[i];//处理请求for (auto item : query){int l = find(item.first), r = find(item.second);cout << s[r] - s[l - 1] << endl;}return 0;
}

Ⅶ. 区间合并

给定多个区间,然后将有交集的区间合并(取并集);

处理如下图的功能:

在这里插入图片描述

实现的思路步骤;

①先利用以区间的左端点为标准排序所有的区间。

②合并:

(1)先将第一个区间的端点作为标准stend;

(2)开始遍历后面的区间:

​ 如果区间的左端点小于标准end并且右端点小于标准的end那么就不用进行操作,直接遍历下一个区间;

​ 如果区间的左端点小于标准end并且右端点大于标准的end那么我们就更新标准的end为当前的区间的右端点;

​ 如果区间的左端点大于标准的end那么我们将当前的标准存储起来(已经称为一个合并后的区间),并且开始从(1)开始执行。

在这里插入图片描述

代码:

#include<iostream>
#include<vector>
#include<algorithm>using namespace std;#define N 100010;typedef pair<int, int>  PII;int n;vector<PII> segs;void merge(vector<PII>& segs)
{vector<PII> res;sort(segs.begin(), segs.end()); // 按照左端点进行排序int st = -2e9, ed = -2e9;for (auto seg : segs)if (ed < seg.first)//判断是否要产生新的区间{if (ed != -2e9) res.push_back({ st, ed });//已经满足合并区间的条件,所以将这个区间存储起来st = seg.first, ed = seg.second; //即将开始合并新的区间,要将第一个区间的端点作为标准}else ed = max(ed, seg.second); //判断合并区间的右端点if (st != -2e9) res.push_back({ st, ed }); // 将最后一个区间存储到答案中segs = res;
}
int main()
{cin >> n;for (int i = 0; i < n; ++i){int l, r;cin >> l >> r;segs.push_back({ l, r });}merge(segs);cout << segs.size();return 0;
}

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述

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

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

相关文章

有效的括号(C)

bool isValid(char* s) {ST st;StackInit(&st);while (*s) //遍历 -- 与\0终止{//是左括号 压栈if (*s ( || *s [ *s {){StackPush(&st, *s);s;}else{//应对样例&#xff1a; ’]if (StackEmpty(&st)){StackDestroy(&st);return false;}//不是左括号 应该就…

Spark MLlib快速入门(1)逻辑回归、Kmeans、决策树、Pipeline、交叉验证

Spark MLlib快速入门(1)逻辑回归、Kmeans、决策树案例 除了scikit-learn外&#xff0c;在spark中也提供了机器学习库&#xff0c;即Spark MLlib。 在Spark MLlib机器学习库提供两套算法实现的API&#xff1a;基于RDD API和基于DataFrame API。今天&#xff0c;主要介绍下Data…

docker k8s

Docker docker到底与一般的虚拟机有什么不同呢&#xff1f; 我们知道一般的linux系统即GNU/Linux系统包括两个部分&#xff0c;linux系统内核GNU提供的大量自由软件&#xff0c;而centos就是众多GNU/Linux系统中的一个。 虚拟机会在宿主机上虚拟出一个完整的操作系统与宿主机完…

在 3ds Max 中对链模型进行摆放姿势处理

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 建模和“摆姿势”3D链可能看起来是一项繁琐的工作&#xff0c;但实际上可以通过使用阵列工具并将链中的链接视为骨骼来轻松完成。在本教程中&#xff0c;我将向您展示如何对链条进行建模&#xff0c;并通过…

oled拼接屏在柳州的户外广告中有哪些应用展现?

柳州oled拼接屏是一种高端的显示屏&#xff0c;它采用了OLED技术&#xff0c;具有高亮度、高对比度、高色彩饱和度、高刷新率等优点&#xff0c;能够呈现出更加真实、清晰、细腻的图像效果。 同时&#xff0c;柳州oled拼接屏还具有拼接功能&#xff0c;可以将多个屏幕拼接在一…

vue element select下拉框回显展示数字

vue element select下拉框回显展示数字 问题截图&#xff1a; 下拉框显示数字可以从数据类型来分析错误&#xff0c;接收的数据类型是字符串&#xff0c;但是value是数字类型 <el-form-item prop"classifyLabelId" :label"$t(item.classifyLabelId)"…

GUI-Menu菜单实例

运行代码&#xff1a; //GUI-Menu菜单实例 #include"std_lib_facilities.h" #include"GUI/Simple_window.h" #include"GUI/GUI.h" #include"GUI/Graph.h" #include"GUI/Point.h"struct Lines_window :Window {Lines_window…

常见的网络攻击

​ 1.僵木蠕毒 攻击业内习惯把僵尸网络、木马、蠕虫、感染型病毒合称为僵木蠕毒。从攻击路径来看&#xff0c;蠕虫和感染型病毒通过自身的能力进行主动传播&#xff0c;木马则需要渠道来进行投放&#xff0c;而由后门木马&#xff08;部分具备蠕虫或感染传播能力&#xff09;构…

Mybatis架构简介

文章目录 1.整体架构图2. 基础支撑层2.1 类型转换模块2.2 日志模块2.3 反射工具模块2.4 Binding 模块2.5 数据源模块2.6缓存模块2.7 解析器模块2.8 事务管理模块3. 核心处理层3.1 配置解析3.2 SQL 解析与 scripting 模块3.3 SQL 执行3.4 插件4. 接口层1.整体架构图 MyBatis 分…

智能优化算法——灰狼优化算法(PythonMatlab实现)

目录 1 灰狼优化算法基本思想 2 灰狼捕食猎物过程 2.1 社会等级分层 2.2 包围猎物 2.3 狩猎 2.4 攻击猎物 2.5 寻找猎物 3 实现步骤及程序框图 3.1 步骤 3.2 程序框图 4 Python代码实现 5 Matlab实现 1 灰狼优化算法基本思想 灰狼优化算法是一种群智能优化算法&#xff0c;它的…

java版工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

cocos creator Richtext点击事件

组件如图 添加ts自定义脚本&#xff0c;定义onClickFunc点击方法&#xff1a; import { Component, _decorator} from "cc";const { ccclass } _decorator; ccclass(RichTextComponent) export class RichTextComponent extends Component{public onClickFunc(even…

C++入门学习(2)

思维导图&#xff1a; 一&#xff0c;缺省参数 如何理解缺省参数呢&#xff1f;简单来说&#xff0c;缺省参数就是一个会找备胎的参数&#xff01;为什么这样子说呢&#xff1f;来看一个缺省参数就知道了&#xff01;代码如下&#xff1a; #include<iostream> using std…

【个人笔记】linux命令之ls

目录 Linux中一切皆文件ls命令常用参数常用命令lscpu lspci Linux中一切皆文件 理解参考&#xff1a;为什么说&#xff1a;Linux中一切皆文件&#xff1f; ls命令 ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容…

实现大文件传输的几种方法,并实现不同电脑间大文件传输

随着网络技术的快速发展&#xff0c;大文件的传输需求越来越多&#xff0c;如何在不同的电脑之间实现大文件的快速传输&#xff0c;是一个挑战&#xff0c;下面介绍几种常用的方法可以解决这个问题。 1、利用局域网传输&#xff1a;把两台电脑接入同一个网络环境&#xff0c;通…

每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户

文章目录 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户每日语录第26题 中级题: 活跃时长的均值1. 需求列表思路分析 答案获取加技术群讨论附表文末SQL小技巧 后记 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户 大家好&#xff0c;我是Maynor。…

AtCoder Beginner Contest 310-D - Peaceful Teams(DFS)

Problem Statement There are N sports players. Among them, there are M incompatible pairs. The i-th incompatible pair (1≤i≤M) is the Ai​-th and Bi​-th players. You will divide the players into T teams. Every player must belong to exactly one team, an…

Web3.0:重新定义数字资产的所有权和交易方式

随着区块链技术的发展和应用&#xff0c;数字资产的概念已经逐渐深入人心。数字资产不仅包括加密货币&#xff0c;还包括数字艺术品、虚拟土地、游戏道具等各种形式的数字物品。然而&#xff0c;在传统的互联网环境下&#xff0c;数字资产的所有权和交易方式往往受到限制和约束…

SQL中为何时常见到 where 1=1?

你是否曾在 SELECT 查询中看到过 WHERE 11 条件。我在许多不同的查询和许多 SQL 引擎中都有看过。这条件显然意味着 WHERE TRUE&#xff0c;所以它只是返回与没有 WHERE 子句时相同的查询结果。此外&#xff0c;由于查询优化器几乎肯定会删除它&#xff0c;因此对查询执行时间没…

猿创征文|一文带你了解前端开发者工具

前端开发者工具目录 一、前言二、前端开发者工具——编译器&#xff08;含插件&#xff09;1、VS Code2、VS Code 必备插件3、WebStorm 三、前端开发者工具——UI 框架工具1、Element2、Vant 四、前端开发者工具——API 调试工具1、ApiPost 五、写在最后&#xff08;总结&#…