算法基础之贪心算法(一)
905. 区间选点给定 N 个闭区间 [ ai, bi ],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
输入格式第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 ai, bi,表示一个区间的两个端点。
输出格式输出一个整数,表示所需的点的最小数量。
数据范围
1≤N≤10^5
−10^9≤ai≤bi≤10^9输入样例:12343-1 12 43 5
输出样例:12
AC
将每个区间按照右端点从小到大进行排序
从前往后枚举区间,end 值初始化为无穷小
如果本次区间不能覆盖上次区间的右端点,即 ed < range[i].l
则需要选择一个新的点,res ++ ; ed = range[i].r;
如果本次区间可以覆盖上次区间的右端点,则进行下一轮循环
时间复杂度 O(nlogn)
证明
证明 ans <= cnt : cnt 是一种可行方案, ans 是可行方案的最优解,也就是最小值
证明 ans >= cnt : cnt 是可行方案的一个区间集 ...
PAT甲级之字符串处理(一)
1001 A+B Format (20 分)Calculate a+b and output the sum in standard format — that is, the digits must be separated into groups of three by commas (unless there are less than four digits).
Input Specification:Each input file contains one test case. Each case contains a pair of integers a and b where −106≤a,b≤106. The numbers are separated by a space.
Output Specification:For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.
Sample Inp ...
彻底搞懂C/C++指针
彻底搞定C指针(上)第一篇 变量的内存实质1. 先来理解C语言中的变量的实质要理解C指针,就必须理解C中“变量”的存储实质。
先理解内存空间,请看下图:
如上图所示,内存只是一个存放数据的空间,同时每个字节均有编号,称为内存地址。
来看一下C/C++语言变量声明:
12int i;char a;
声明变量时,其实是在内存中申请了一个名为 i 的整型变量宽度的空间(现代的64位处理器中其宽度都是4个字节),和一个名为 a 的字符型变量宽度空间(占1个字节)。
内存中的映像可能如下图:
图中看出,i 在内存起始地址为6上申请了四个字节的空间(我这里默认为64位操作系统),并名为 i 。同理,a 在内存地址为10上申请了一字节的空间,并命名为 a 。
2. 赋值给变量再看下面的赋值
12i = 30;a = 't';
3. 查看变量地址代码如下:
1printf("%x", &i);
以上图映像为例,则显示 i 的内存地址编号6。
第二篇 指针是什么1. 指针是什么先看一条声明一个指向整型变量的指针的语句:
1int* pi;
pi 是 ...
Self_learing Tasks
Self-learning Tasks
C++ :
[ 菜鸟教程 ] https://www.runoob.com/cplusplus/cpp-tutorial.html
[ B站最好的C++教程 ] https://www.bilibili.com/video/BV1VJ411M7WR
Java :
[ B站尚硅谷 ] https://www.bilibili.com ...
长度最小的子数组
长度最小的子数组给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:target = 7, nums = [2,3,1,2,4,3]输出:2解释:子数组 [4,3] 是该条件下的长度最小的子数组。
暴力解法这道题目的暴力解法自然是通过两个 for 循环,不断遍历寻找符合条件的子序列,该算法时间复杂度为 O(n^2)。
1234567891011121314151617181920class Solution {public: int minSubArrayLen(int target, vector<int>& nums) { int result = INT_MAX; //存储最终结果,初始化为INT_MAX int sum = 0; // 子序列的数值之和 int subLength = 0; // 子序列的长度 for (int i = 0; i < nums.si ...
移除元素
移除元素
题目地址:https://leetcode-cn.com/problems/remove-element/
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。
示例 2:给定 nums = [0,1,2,2,3,0,4,2], val = 2,函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
思路可能一上来就想着直接那相应的元素删除就好了
要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖
暴力解法这个题目暴力的解法就是两层 for 循环,一个 for 循环遍历数组元素,另一个 for 循环更新数组。
删除过程如下:
很明显, ...
二分查找
二分法查找题目链接:https://leetcode-cn.com/problems/binary-search/
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:输入: nums = [-1,0,3,5,9,12], target = 9输出: 4解释: 9 出现在 nums 中并且下标为 4
示例 2:输入: nums = [-1,0,3,5,9,12], target = 2输出: -1解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
思路这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找返回的元素下标就可能不是唯一的。这些都是使用二分法的前提条件,当看到题目描述满足上述条件的时候,需要想一想是否可以使用二分法。
二分法查找涉及很多边界条件,逻辑 ...
数组理论基础
数组理论基础数组在内存中的存储方式
数组是存放在连续内存空间上的相同类型数据的集合。数组可以方便的通过下标索引的方式取到下标对应的数据。
如图所示:
需注意两点:
数组下标都是从0开始的
数组内存空间的地址是连续的。
正因为数组在内存空间的地址是连续的,所以我们在删除或者插入元素时,需要移动其他元素的地址。例如删除下标为3的元素,需要对下标为3的元素后面的所有元素做移动操作,如图所示:
且当使用C++时,需要注意 vector 和 array 的区别,vector 的底层实现是 array,严格来讲 vector 是容器,不是数组。
数组元素时不能删除的,只能覆盖。二维数组请看图
二维数组在内的空间地址是连续的吗?不同编程语言的内存管理是不一样的,以C++为例,在C++中 二维数组是连续分布的。
以一个实验例子为证,C++测试代码如下:
123456789101112void test_arr() { int array[2][3] = { {0, 1, 2}, {3, 4, 5} }; ...
04-管程
为什么引入管程
信号量机制存在的问题:编写程序困难,易出错由于这个原因,人们想设计一种机制,让程序员编写程序时不在需要关注复杂的PV操作
定义和基本操作
管程是一种特殊的软件模块,由下列部分组成
局部于管程的共享数据结构说明
对该数据结构进行操作的一组过程(函数)
对局部于管程的共享数据结构设置初始值的语句
管程有一个名字
基本特征
局部于管程的数据只能被局部于管程的过程所访问
一个过程只有通过调用管程内的过程(函数)才能进入管程访问共享数据 (也就是说管程只能通过管程内部的函数来进行访问)
每次仅允许一个进程在管程内执行某个内部过程
管程中会设置条件标量和等待唤醒操作,以解决同步问题,同时管程也能很好的处理互斥的问题
引入管程的目的:更加方便的实现进程的互斥和同步
需要在管程中定义共享数据
需要定义访问数据的“入口”——其实就是函数
只有通过“入口”才能访问共享数据
管程中有很多入口,但是每次只能开放其中一个,并且只能让一个线程或线程进入(这种互斥是由编译 器实现的,不需要程序员关心)
可在管程中设置条件变量以及等待/唤醒操作已解决同步问题。可以让进程等待或线 ...