欢迎回到:遇见蓝桥遇见你,不负代码不负卿!
目录
好久不见啦铁汁们,蓝桥杯更新咯,快来尝尝鲜叭。
【前言】:由于本章基础知识点不多,所以笔者直接讲解四道典型题让大家感受一下二分法的美妙。

准备开始咯,坐稳哈...
【敲黑板】:用二分算法解题的前提是该数组有序!!!
【注意】:查找一次砍掉一半,效率非常高!但是条件比较苛刻,一定要有序!
给定一个 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
设定左右指针
找出中间位置,并判断该位置值是否等于 target
nums[mid] == target 则返回该位置下标
nums[mid] > target 则右侧指针移到中间
nums[mid] < target 则左侧指针移到中间

二分是一个比较简单的算法,只要大家记住上面这种套路就行啦。
int search(int* nums, int numsSize, int target){
//考虑特殊情况
if(nums == NULL || numsSize == 0){
return -1;
}
int left = 0;//起始元素的索引
int right = numsSize - 1;//末尾元素的索引
int mid = 0;
while(left <= right){
//应该有很多人会写成mid = (left + right) / 2;这种写法不谨慎
//因为做的是加法运算,所以要考虑溢出的特殊情况
mid = left + (right - left) / 2;
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid - 1;
}else{
return mid;
}
}
return -1;
}
【注意】:while判断表达式中是left <= right, 为什么还要加上left == right 的情况呢,当二者相等的时候说明还有一个元素需要被比较,所以当left > right时停下来,因为此时中间已经没有元素需要被比较了。至于为什么将mid = left + (right - left) / 2; 的形式,上面代码中已经讲咯。
时间复杂度:O(logN)
空间复杂度:O(1)
看,二分法是很高效的,大家在今后的训练中,如果遇到查找搜索类的题目要求时间复杂度是O(logN)的,要想到二分法哦。
好嘞,这就是二分查找,是不是很简单,下面再补充几道典型例题,让大家熟悉二分。
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
题目中要求使用时间复杂度为O(logN)的算法解题,所以结合本题题意,很容易就想到了二分法。
示例1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例2:
输入: nums = [1,3,5,6], target = 7
输出: 4
- 整体思路和普通的二分查找几乎没有区别,先设定左侧下标 left 和右侧下标 right,再计算中间下标 mid
- 每次根据 nums[mid] 和 target 之间的大小进行判断,相等则直接返回下标,nums[mid] < target 则 left 右移,nums[mid] > target 则 right 左移
- 查找结束如果没有相等值则返回 left,该值为插入位置,注意哦,最后如果没有相等值,返回的是left
【注意】:
二分查找的思路不难理解,但是边界条件容易出错,比如 循环结束条件中 left 和 right 的关系,更新 left 和 right 位置时要不要加 1 减 1。这些都是大家自己动手画图理解,用代码去体会,只可意会不可言传哦。
int searchInsert(int* nums, int numsSize, int target){
//考虑特殊情况
if(nums == NULL || numsSize == 0){
return -1;
}
int left = 0;
int right = numsSize - 1;
int mid = 0;
while(left <= right){
mid = left + (right - left) / 2;
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;
}
}
return left;
}
时间复杂度:O(logN)
空间复杂度:O(1)
是不是很简单,下面开始蹭加点难度咯,有点绕,需要仔细想哦,加油加油。

峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
示例1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
【注意】:二分法解题的前提要求是有序的,这题看起来没说有序呀,那怎么还能用二分法呢,我们也不能先进行排序,因为会把索引打乱,那该怎么办呢,请朝后看...

描述这个规律就是:
- 规律一:如果nums[mid] > nums[mid+1],则在mid之前一定存在峰值元素
- 规律二:如果nums[mid] < nums[mid+1],则在mid+1之后一定存在峰值元素
int findPeakElement(int* nums, int numsSize){
//考虑特殊情况
if(nums == NULL || numsSize == 0){
return -1;
}
int left = 0;
int right = numsSize - 1;
int mid = 0;
while(left <= right){
if(left == right){
return left;
}
mid = left + (right - left) / 2;
if(nums[mid] > nums[mid + 1]){
right = mid;//mid之前一定存在峰值元素
}else{
left = mid + 1;//mid+1之后一定存在峰值元素
}
}
return left;
}
时间复杂度:O(logN)
空间复杂度:O(1)
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
也就是说,整个二维数组都是升序的。
示例1:

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例2:

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false

【注意】:本题的重点就在于一维索引和二维索引间的互换
bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target){
//考虑特殊情况
if(matrix == NULL || matrixSize == 0){
return false;
}
int row = matrixSize;//行数
int col = *matrixColSize;//列数
int left = 0;//起始元素的索引
int right = row * col - 1;//最后一个元素的索引
int mid = 0;
int element = 0;
while(left <= right){
mid = left + (right - left) / 2;
element = matrix[mid / col][mid % col];//将一维的索引化成二维的索引
if(element == target){
return true;
}else if(element > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
return false;
}
复杂度分析
时间复杂度:O(logM*N), M,N分别是矩阵的行数和列数
空间复杂度:O(1)
好喽,铁汁把上面四道题目练习一遍,肯定就能对二分算法有一定的认识,加油加油哦。
大家先将上篇博文(分治算法)看一下,现在讲解那道留下的思考题。
蓝桥杯算法竞赛系列第三章——细谈递归的bro分治_安然无虞的博客-CSDN博客
给定一个整数数组,找到一个具有最大和的连续子数组(子数组中至少包含一个数),要求返回其最大和。
注意:本题要求的是连续的子数组,可能有的题目要求可以是断开的,但本题不是。
将数组nums由中点mid分为三种情况:
1. 最大子串在左边
2. 最大子串在右边
3. 最大子串跨中点,左右两边元素都有(理解上的难点)

lSum 表示 [l,r] 内以 l 为左端点的最大子段和
rSum 表示 [l,r] 内以 r 为右端点的最大子段和
mSum 表示 [l,r] 内的最大子段和
iSum 表示 [l,r] 的区间和
struct Status {
int lSum, rSum, mSum, iSum;
};
struct Status pushUp(struct Status l, struct Status r) {
int iSum = l.iSum + r.iSum;
int lSum = fmax(l.lSum, l.iSum + r.lSum);
int rSum = fmax(r.rSum, r.iSum + l.rSum);
int mSum = fmax(fmax(l.mSum, r.mSum), l.rSum + r.lSum);
return (struct Status){lSum, rSum, mSum, iSum};
};
struct Status get(int* a, int l, int r) {
if (l == r) {
return (struct Status){a[l], a[l], a[l], a[l]};
}
int m = l + (r - l) / 2;
struct Status lSub = get(a, l, m);
struct Status rSub = get(a, m + 1, r);
return pushUp(lSub, rSub);
}
int maxSubArray(int* nums, int numsSize) {
return get(nums, 0, numsSize - 1).mSum;
}
由于想让大家搞懂知识点,所以这里的题目可能用这种解法不是最优解,没关系,我会在后面的算法中补充到,在每日一题中也会涉及到。今天就不布置思考题咯,铁汁们好好把上面题目自己尝试做出来。
嘿嘿,期待铁汁们留言点评,如果能够再动动小手,给博主来个三连那就更好啦,您的认可就是我最大的动力!求求啦~~

关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于
我使用irb。下面是我写的代码。“斧头”..“bc”我期待"ax""ay""az""ba"bb""bc"但结果只是“斧头”..“bc”我该如何纠正?谢谢。 最佳答案 >puts("ax".."bc").to_aaxayazbabbbc 关于ruby-从结束值创建一系列字符串,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7617092/
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言: 在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC 已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析 这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy
使用RubyonRails,我使用给定的增量(例如每30分钟)用时间填充“选择”。目前我正在YAML文件中写出所有的可能性,但我觉得有一种更巧妙的方法。我想我想提供一个开始时间、一个结束时间、一个增量,并且目前只提供一个名为“关闭”的选项(想想“business_hours”)。所以,我的选择可能会显示:'Closed'5:00am5:30am6:00am...[allthewayto]...11:30pm谁能想出更好的方法,或者只是将它们全部“拼写”出来的最佳方法? 最佳答案 此答案基于@emh的答案。defcreate_hour
我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s