![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
藍橋杯
包括:漢洛塔、位運算、查找、递归、暴力、排序、二维数组和矩阵、尺取
羡云不羡君
这个作者很懒,什么都没留下…
展开
-
蓝桥真题-幂一矩阵
题目:天才少年的邻居 atm 最近学习了线性代数相关的理论,他对“矩阵”这个概念特别感兴趣。矩阵中有个概念叫做幂零矩阵。对于一个方阵 M ,如果存在一个正整数 k 满足 M^k = 0 ,那么 M 就是一个幂零矩阵。(^ 表示乘方)atm 不满足幂零矩阵,他自己设想了一个幂一矩阵:对于一个方阵 M ,如果存在一个正整数 k 满足 M^k = I ,其中 I 是单位矩阵,那么 M 就是一个幂一矩阵。atm 特别钟情于这样一种方阵:每行每列有且仅有一个 1 。经过 atm 不断实验,他发现这种矩阵都原创 2022-03-09 10:30:02 · 115 阅读 · 0 评论 -
求子矩阵最大累加和
题意:解题思路:把第0行,定义为起始行; 刚开始的时候只是这一行(那么这就可以看成一个以为数组,这一行的最大累加和就可以求得),然后以起始行为标准(这个子矩阵有两行了),因为我们知道这个子矩阵必然是有两行的,所以我们就可以可以把上下两行加在一起,变成一行,然后就又可以求出最大的了。同理,这个子矩阵有三行也是一样的。同理,我们也可以把起始行定义为第一行,第二行,那么所有子矩阵的情况都有了。代码:import java.util.Arrays;public class 子矩阵最大累加和 {原创 2022-02-12 15:03:19 · 298 阅读 · 0 评论 -
求一个数组中最大的累加和(连续的区间)
法1:通过枚举的方法依次求出每种可能性的sum值,然后找到最大的。时间复杂度O(n)法2:单项扫描:例如:arr[] = {1,-2,3,5,-2,6,-1}public class 子数组最大累加和 { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {1,-2,3,5,-2,6,-1}; int sum = findmaxsum原创 2022-02-12 12:46:23 · 401 阅读 · 0 评论 -
将0所在的行列清零-二维数组和矩阵
public class 将零所在的行列清零 { public static void main(String[] args) { // TODO Auto-generated method stub int[][] arr = {{1,2,3,4}, {5,6,0,8}, {9,10,11,12}, {13,14,15,16}}; solve(arr); Print(ar...原创 2022-02-10 10:23:24 · 442 阅读 · 0 评论 -
总和不小于S的连续子序列的长度的最小值-尺取法
public class 连续和不小于S的最短子序列 { static int S = 15; public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {5, 1, 3, 5, 10, 7, 4, 9, 2, 8}; int sum = 0; int begin = 0; int end =0; int left = 0; int...原创 2022-02-15 12:05:38 · 163 阅读 · 0 评论 -
快排之三指针分区算法
三指针分区思路:与单向扫描分区类似只不过三指针分区把与主元相等的分成一个区间。所以和单向扫描一样有一个扫描指针和末指针。多的一个equal指针用来指向与主元相等区间的首元素。最开始的时候第一个元素为主元,e(equal指针),s(扫描指针),b(末指针)与单向扫描一样,通过判断扫描指针所指的元素大小如果等于主元 S(扫描指针)右移一个如果小于主元 e和s的位置交换,e++,s++如果大于主元 s和b交换,b--这样就会形成下面的局面...原创 2022-02-01 16:33:29 · 659 阅读 · 0 评论 -
基础排序之希尔排序
希尔排序也相当于一种插入排序,它是简单插入排序经过改进过后的一种更高效的的版本,也称为缩小增量排序,最开始的增量是arr.length/2.import java.util.Arrays;public class 希尔排序 { public static void main(String[] args) { // TODO Auto-generated method stub int arr[]= {1,8,6,7,2,3,4,1,5,7}; shellsort(arr);原创 2022-01-27 14:32:22 · 321 阅读 · 0 评论 -
题1:合并有序数组-归并排序思想;题2:逆序对个数-归并
题目1:给定两个排序后的数组A和B,其中A的末端有足够的缓存空间容纳B,编写一个方法将A并入B并排序思路:两个有序的数组合并就是归并排序里面的归并步骤可参考:基础排序之归并排序_羡云不羡君的博客-CSDN博客题目2:一个数列,如果左边的数大,右边的数小,则称这两个数为一个逆序对,求一个数列中有多少个逆序对。给定一个乱序数组arr首先要知道:归并排序:这两个有序数列竖着放了(方便理解)对这两个有序的序列归并的时候 :如果左指针所指元素大于右指针所指元素,则说明...原创 2022-02-08 15:00:50 · 554 阅读 · 0 评论 -
基础排序之冒泡排序
冒泡排序理解:假设这里有一个数组int[] arr = new int[]{5,6,8,2,4,3,6},然后arr[0]与arr[1]比较,如果arr[0]>arr[1],它们就交换位置,否则就不变。然后arr[1]与arr[2]比较,如果arr[1]>arr[2],它们就交换位置,否则就不变。........就这样直到整个数组都比较完,这样就可以把最大的一个数排到最前面,第二大的数同理,其余数也同理。import java.util.Arrays;public cl原创 2022-01-25 20:09:48 · 292 阅读 · 0 评论 -
基础排序之归并排序
归并排序算法完全依照了分治模式-分解:将n个元素 分成各含n/2个元素的子序列-解决:对两个子序列递归的排序-合并:对两个已经排好序的子序列进行合并归并排序与快排的区别快排主要是着重于划分(后面就不用合并了);归并排序主要着重于对合并(没有划分即找到主元让主元的左边比主元小,右边比主元大)...原创 2022-02-06 18:24:15 · 432 阅读 · 0 评论 -
基础排序之选择排序
选择排序理解:假设给了一个数组arr[]={4,5,6,2,3,8,9,15,2} 首先我们会在数组中所有元素(共9个)中去选择一个最大的数,然后把这个数与天花板上的数 交换位置(也就是2的位置) 然后,剩余的八个元素中在去找到最大的数,放到天花板上(也就是15所在的位置) 后面以此类推 直到天花板的位置下标为0import java.util.Arrays;public class 选择排序 { public static void main(String[] ar...原创 2022-01-25 20:53:39 · 95 阅读 · 0 评论 -
基础排序7之堆排序
堆化:定义:把一个乱序的数组变成一个大顶堆或者小顶堆堆化对堆排序有重要作用,后面会阐述如何让给定的一个数组实现堆化:(这里我们以大顶堆为例)假设这里有个数组arr[]={1,8,5,6,2,4,11}对应的二叉树的形式这里我们先找到最后一个非叶子节点(arr.length/2-1),为什么是arr.length/2-1?首先我们知道已知子节点i则父节点:(i-1)/2,而最后一个非叶子节点的子节点一定是arr.length-1。这里我们找到最后一个非叶子节点5后,然后把 这一小部原创 2022-02-08 18:14:25 · 646 阅读 · 0 评论 -
前k个数-小顶堆
题目:求海量数据(正整数)按逆序排列的前k个数(topk),因为数据量太大,不能全部存储在内存中,只能一个一个的从磁盘或者网络上读取数据,请设计一个高效的算法来解决这个问题。第一行:用户输入输入K,代表要求得topk随后的N(不限制)行,每一行是一个整数代表用户输入的数据用户输入-1,代表输入终止请输出topk,从小到大,空格分隔。题意理解:这道题意思就是这里有很多数,我们需要一个一个输进去,然后找到最大的前K个数,按从小到大的顺序输出。解题思路:因为我们最后只需要输出k个数,所以我原创 2022-02-09 17:04:37 · 623 阅读 · 0 评论 -
第k个元素-快排思想
题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k个元素值。原创 2022-02-07 10:29:53 · 262 阅读 · 1 评论 -
快排之双向扫描分区法
双向扫描的思路是:头尾指针往中间扫描,从左找到大于主元的元素,从右找到小于等于主元的元素二者交换,继续扫描,直到左侧无大元素,右侧无小元素。import java.util.Arrays;import lanqiao.Swap;public class 快排双向指针 { public static void main(String[] args) { // TODO Auto-generated method stub int arr[] = new int[5]; Swap.原创 2022-02-01 11:55:20 · 1080 阅读 · 0 评论 -
快排优化2种方法找主元使得分区的时候均分提高效率
起因:前面我们写的快排,在划分(分区)的时候无论是一遍单向扫描,双向扫描还是三指针分区法都是把第一个元素定义为主元,所以说划分的时候可能并不均匀(不是一半一半划分的),最坏的情况下可能导致时间复杂度变为O(n^2),而快排理想的是O(n*lgn).法一:三点中值法public static int patitiion(int[] arr,int start,int end) { //优化,在start,end,mid中找主元 int midindexof = start+((en原创 2022-02-02 16:30:46 · 601 阅读 · 1 评论 -
计数排序通用-无论正负数
计数排序计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。分析时间复杂度:扫描一次source,扫描一个helper,复杂度为N+K空间复杂度:辅助空间 k ,k =maxOf(source) - minOf(source) +1非原址排序稳定性:相同元素不会出现交叉,非原址都是拷来考去计数有缺点,数据密集或者范围小时,适用而且当 O原创 2022-02-10 10:13:50 · 723 阅读 · 0 评论 -
基础排序之插入排序
插入排序理解:假设给定一个数组arr[]={1,8,3,6,5,7,12,6}首先摸起第一个数1,然后然该数与第二个数8比较,1<8所以不用调整,然后右移一位到8的位置上,与前面一个数(3)比较发现需要调整位置(8与3交换),然后1与3比较(不用调整)。此时已经排好了数列1,3,8.后面的6也是如此(按照大小插入到前面排好的数列中去)。import java.util.Arrays;public class carupaixu { public static void main(St原创 2022-01-26 17:38:18 · 346 阅读 · 0 评论 -
快排与归并思想的例题--调整数组顺序使奇数位于偶数前面
题目:调整数组顺序使奇数位于偶数前面:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前面部分,所有的偶数位于数组的后面部分。要求时间复杂为o(n).解题思路:思路一:归并排序里面归并步骤的时候的思想时间复杂度O(n)与归并排序想法一样都是开辟一个辅助空间通过current指针移动去判断每一个元素的奇偶性,奇数就填到Left所指位置,偶数的话就填到right所指位置思路二:快排里面的一遍单项扫描分区法给这个数组两个指针分别指向头部和尾部,当头指针遇到偶数的时候停下来原创 2022-02-06 19:26:56 · 639 阅读 · 0 评论 -
最小可用ID
题目:在非负数组(乱序)中找到最小可分配的id(从1开始编号),数据量1000000(就是找到从1开始最小的一个数:在数组中没有出现过的最小的数)数组中的数是【1,1000000】方法1:暴力:从1开始依次探测每个自然数是否在数组中 O(n^2)public class 最小可用ID { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr= {5,4,3,1,原创 2022-02-07 17:02:14 · 323 阅读 · 0 评论 -
超过一半的数字
题目:数组中有一个数字出现的次数超过了数组长度的一半(大于一半),找出这个数字。解法一:排序后返回arr[N/2],N为数组的长度。O(nlg(n))代码:排序直接调用Arrays.sort(arr);解法二:hash统计解法三:等价于找第N/2小的元素。O(n)注意:这种方法会改变数组里面的元素顺序代码:可以参考:第k个元素-快排思想_羡云不羡君的博客-CSDN博客解法四:不同的数进行消除public class 超过一半的数字 { public static void原创 2022-02-07 11:57:40 · 97 阅读 · 0 评论 -
递归之斐波那契数列
多分支递归:斐波那契数列(分解为多个小规模的子问题)public class 斐波那契数列 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(fib(3)); } //执行顺序先纵后横(深搜) public static int fib(int n) { if(n==1||n==2) ...原创 2022-01-23 15:46:27 · 201 阅读 · 0 评论 -
递归基础练习1
一.求n的阶乘1.找重复:n*(n-1)!,求(n-1)!是原问题的重复(规模更小)——子问题。2.找变化:重复中变化的量应该作为参数。3.找边界:递归的出口。public class 求N的阶乘 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(fun(3)); } public static int fun(原创 2022-01-23 12:07:42 · 374 阅读 · 0 评论 -
递归-上楼梯问题
思路:因为一次可以上1阶,2阶或者3阶,所以上n阶楼梯的上法就是=先上1阶后的上法+先上2阶后的上法+先上3阶后的上法(这里就是3个子问题的相加)所以就可以表示成f(n)=f(n-1)+f(n-2)+f(n-3)最后找到递归出口就行了。(这里递归出口有多种看自己怎么想了)例如:当n=0的时候返回1(已经走完楼梯了是一种方法)n<0的时候返回0。或者像这样 if(n==3) return 4; if(n==1) return 1; if(n==2) ret原创 2022-01-27 17:34:54 · 1113 阅读 · 0 评论 -
递归之插入排序
import java.util.Arrays;public class 递归之插入排序 { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {6,2,8,5,1}; insertsort(arr,arr.length-1); System.out.println(Arrays.toString(arr)); } .原创 2022-01-24 13:30:02 · 869 阅读 · 0 评论 -
递推之求最大公约数
最大公约数:(求25,10的最大公约数)25 10 25%10=15因为这里15>10所以 15 10 15%10=510 5 10%5=0所以最大公约数是5public class 最大公约数 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(fun(25,15)); } public sta..原创 2022-01-23 19:38:44 · 447 阅读 · 0 评论 -
快速求a的n次方
这可以用一个for循环去求但是时间复杂度是O(n),而我们通过下面方法可提高效率public class 快速求a的n次方 { public static void main(String[] args) { // TODO Auto-generated method stub int res = pow(2,1); System.out.println(res); } public static int pow(int a,int n) { int原创 2022-01-30 21:05:59 · 1404 阅读 · 0 评论 -
递归之汉诺塔
游戏里有三根柱子(A,B,C),A柱子上从下往上按照大小顺序摞着N片圆盘。玩家需要做的是把圆盘从下面开始按从大顺序重新摆放在B柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。找重复:原问题是:把1-N从A移到B,A为源,C为辅助子问题就是把1-N-1从A移动到C,B为辅助所以原问题就可以等价于{1.把1-N-1从A移动到C,B为辅助2.把第N个盘子从A移动到B3.把辅助盘上的N-1个盘子放到目标盘上}public class 递归之汉诺塔原创 2022-01-24 18:26:38 · 2220 阅读 · 0 评论 -
分治法典型体现之快速排序(一遍单项扫描)
将原问题划分成若干个规模较小而结构与原问题一致的子问题;递归的解决这些子问题,然后在合并其结果,就得到原问题的解容易确定运行时间,是分治算法的优点之一。分治模式在每一层都递归上都有三个步骤:-分解:将原问题分解成一系列的子问题-解决:递归的解决子问题,若子问题足够小,则直接有解。-合并:将子问题的结果合并成原问题的解分治的关键点-原问题可以一直分解为形式相同的子问题,当子问题规模较小时可以自然求解。-子问题的解通过合并可以得到原问题的解。-子问题的分解以及解的合并一定是...原创 2022-01-31 18:23:50 · 585 阅读 · 0 评论 -
旋转数组最小数字-二分查找
详细代码以及性能对比import java.util.Scanner;public class 旋转数组的最小值 { /* *使用改造二分法提高性能(这里使用选择排序的内核也可以但是性能没有二分法的高:选择排序的内核时间复杂度是:n,而二分法的时间复杂度是lgn) 把一个数组最开始的若干元素搬到数组的末尾,我们称之为数组的旋转,输入一个递增排序的数组的一个旋转,输出旋转数组中的最小值。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转该数组的最小值为1 {1,2,3原创 2022-01-27 20:09:50 · 2857 阅读 · 0 评论 -
递归之二分查找
public class 递归之二分查找 { //low是开始下标,high是结束下标,key是要查找的值 public static int binarySearch1(int[] arr,int low,int high,int key) { //递归出口 if(low>high) { return -1; } int mid = low+((high-low)>>1); int midVal = arr[mid.原创 2022-01-24 19:44:12 · 154 阅读 · 0 评论 -
有空字符串的有序数组的查找
问题:有个排序后的字符串数组,其中散布这一些空字符串,编写一个方法,找出给定字符串的索引(肯定不是空字符串)对于这种有序的用二分法public class 有序字符串中查找 {/* 有个排序后的字符串数组,其中散布这一些空字符串,编写一个方法,找出给定字符串的索引(肯定不是空字符串) */ public static void main(String[] args) { // TODO Auto-generated method stub String[] arr..原创 2022-01-29 16:19:54 · 279 阅读 · 0 评论 -
顺序查找与二分查找
/* 题目:设计一个方法用于在指定的数组中查找指定的值,如果找到就返回下标,如果没有找到就返回-1. */public class 顺序查找 { public static void main(String[] args) { // TODO Auto-generated method stub int index = binarySearch(new int[] {1,2,3,5,9},9); System.out.println(index); } /.原创 2022-01-25 10:38:31 · 221 阅读 · 0 评论 -
位运算的奇巧淫技
一.唯一成对的数:1-100然后随机生成一个1-100之间的数,使一个数成对(法1:异或。法2:构造辅助数列)import java.util.Random;public class Arraychengdui { public static void main(String[] args) { int N = 101; int [] arr = new int[N]; for (int i = 0; i < .原创 2022-01-20 19:57:11 · 442 阅读 · 0 评论 -
位运算的奇巧淫技例题补充
例题5:0-1间浮点实数的的二进制表示 给定一个介于0-1之间的实数,(如0.625),类型为double,打印它的二进制表示。如果该数字无法精确的用32位以内的二进制表示则打印“ERROR”。public class 二进制小数 { public static void main(String[] args) { // TODO Auto-generated method stub double num = 0.625; StringBuilder ..原创 2022-01-22 15:24:41 · 210 阅读 · 0 评论