算法套路
数组链表字符串
爱抖腿的嘻嘻嘻
这个作者很懒,什么都没留下…
展开
-
双指针8.采购方案
在数组中选两个数字达到目的选两个数字如果是目标和,则可以直接移动指针,如果是一个小于等于目标和的数,则在lo到hi符合条件时,hi-lo个数都可以符合条件。class Solution { public int purchasePlans(int[] nums, int target) { Arrays.sort(nums); int lo=0; int hi=nums.length-1; int res=0; wh原创 2021-04-06 12:26:45 · 215 阅读 · 0 评论 -
滑动窗口--替换后最长重复字符子串424
给一个全部是大写字母的字符串,可以替换k次,求替换k次之后字符串中最长的重复子串的长度。首先这个题是连续子串,用滑动窗口法,且是求最长字符串,所以先移动end,当移动到不符合要求时,可以左右一起推进一格(因为此时即使是start先移动,也不可能有比之前更好的答案,最多就是持平,所以干脆全都移动一次)怎么判断是否符合条件,也就是看窗口中最多的重复字符有几个,再加上k就是可以出现的最长字符串,可以用一个哈希表来记录窗口中最多的字符串,如果用HahMap的话,就可以用A到Z来表示各个key,value是出现次原创 2020-12-19 03:22:39 · 442 阅读 · 0 评论 -
滑动窗口--最小覆盖子串 76
给了字符串s和t,输出包含所有t中字符(注意是所有,1个字母有两次要输出两次)的最小长度的s的子串首先子串想到用滑动窗口,然后用start表示字符串开始,end表示结束,这个一定要等到start遍历完才知道什么时候完成。所以用while。首先start不动,end移动,直到包含了所有的t中的字符,这时开始移动start,移动直到不包含所有的字符之后,end再动,最终输出包含所有字符时最小的字符子串。如何判断是否包含所有字符呢,用一个hashmap来存储t中的所有字符以及它的个数,然后用另一个hashm原创 2020-12-18 10:32:07 · 62 阅读 · 0 评论 -
差分数组
换句话说就是求字符串2有没有字符串1排列的子串既然是子串,用的就是滑动窗口,窗口大小和字符串1相同,判断条件就是当前子串中是否有所有字符串1中的全部字符。其中字母都是小写字母,所以用一个数组来代替哈希表。记住如果用HashMap,那用到其中的值的时候要把Intege转成int来比较,不能直接用==来比较两个Integer值。class Solution { int[] map1=new int[26]; int[] map2=new int[26]; public b原创 2020-12-19 13:42:46 · 142 阅读 · 1 评论 -
滑动窗口--字符串排列 567
给定s1和s2两个字符串,判断s2是否包含s1的排列,也就是s1是不是s2的子串。这里其实用固定窗口的滑动窗口就可以,不过这样也可以写,只不过条件要写成end-start==l1,不是while循环了。class Solution { int[] map1=new int[26]; int[] map2=new int[26]; public boolean checkInclusion(String s1, String s2) { if(s1.length()原创 2021-03-27 11:13:10 · 67 阅读 · 0 评论 -
前缀和--和为k的数组 560
求一个数组中连续数字的和为k的子数组个数。一开始想到是滑动窗口,但是滑动窗口并不能解决,因为有负数,所以走过的还可能要用到。又想到动态规划,也不行,因为状态转移式推不出来。难道只能用枚举,固定每一个起点的i,然后for循环每一个终点来检查了吗,答案是否定的,可以对检查这一步进行优化。从而O(n)结束。就是利用前缀和若定义pre(i)是0到i的所有数的和,则一个j到i的子数组的和为k就可以表达为pre(i)-pre(j-1)=k所以需要满足pre(j-1)=pre(i)-k所以考虑以i结尾的原创 2021-03-01 23:38:33 · 141 阅读 · 0 评论 -
数对排序--根据身高重建队列406
整数对(h,k)表示h是身高,k是排在这个人前面大于等于h的人数。有一个数组存储了这些数对,但它的顺序并不是按照这个顺序来排列的经过处理之后要求得到按照他们各自属性相符顺序的数组。对于这种数对还涉及排序的问题,一般要根据第一个元素正向排序,根据第二个元素反向排序。我们对于这个题来说就按照身高先逆序排序,然后按照k来升序排序,因为这样排之后可以发现每个元素前面的元素都是大于等于它的元素,而k按升序说明可以把k更大的数放后面,减少操作次数。排序好之后把各个数插入到它的k所在的位置。class Solu原创 2021-02-25 17:43:42 · 202 阅读 · 0 评论 -
单调栈--最大矩形85
这道题类似于求最大正方形,但最大正方形是右下角的点即可代表最大正方形的边长,利用动态规划可以解决。但长方形不同,它可以更好的利用求柱状图中的最大面积来求,每次求一层的最大矩形,当把所有层都求完时就可以求出最大矩形,要注意的是传入的数组不是每次都加等于,而是等于1是加等于,等于0就直接是0了,因为如果有一行是0,这一列也构不成一个完整的全是1的矩形。class Solution { public int maximalRectangle(char[][] matrix) { int原创 2021-02-07 11:46:28 · 68 阅读 · 0 评论 -
单调栈--柱状图中最大的矩形84
类似于接雨水,接雨水要算每一个位置可以装的水,然后叠加起来。每个位置装的水可由两边的最大值中的最小值决定,所以双指针法可以确定此时左边和右边的最大值,然后选较小的一个来确定另外一边可装的水。当然这个水是在高度的上方装的,所以此时装的水为较小的最大值减另外一边的数组高度。而最大矩形是必须连着的在高度内部的,所以确定的是以每个高度为高的矩形的最大面积,最后选一个最大的。遍历开始,什么时候能确定以这个高度为高的矩形的宽呢,就是等到出现第一个高度小于这个数的地方。也就是只要当前矩形的高度是小于前一个的,则总会原创 2021-02-04 19:18:42 · 67 阅读 · 0 评论 -
二分7.求一个排序数组中一个数的第一个和最后一个位置
就是分成两个函数来分别求数组中的数的位置,有注意的就是就算等于目标数也不结束,所以要写if,else if 和else,别分开。class Solution { public int[] searchRange(int[] nums, int target) { if(nums==null || nums.length==0)return new int[]{-1,-1}; int start=binarySerchStart(nums,target,0,nums.原创 2021-01-25 21:56:41 · 105 阅读 · 0 评论 -
二分6.旋转数组plus
要在旋转数组中找到给定的值,就需要分情况讨论了,重点是找到分割后的两部分哪部分是有序的,根据有序的部分可以找到向哪继续下一步的查找第一种情况,0到mid没旋转有序,则若目标值在mid和lo之间, 则hi=mid第二种情况,0到mid没旋转,要找的值在mid到hi,则lo=mid第三种情况,0到mid旋转了,要找的...原创 2021-01-25 19:28:46 · 53 阅读 · 0 评论 -
最长连续序列
给一个未排序的序列,找出其中最长的连续序列的长度。对于每个数都查找在数组中有没有x+1,x+2一直到最长。可以用一个hashset来存储数组中的数,这样可以很方便的判断有没有x+1…,但这样还是外层循环一次,内部循环o(n),因为当找到x到x+n是连续数组后,碰到x+1还要重新找一遍,则在外部遍历的时候,如果找到x-1存在,则从x开始就不可能是最长了,直接跳过。class Solution { public int longestConsecutive(int[] nums) {原创 2021-01-19 23:07:28 · 53 阅读 · 0 评论 -
最短无序子数组
求一个数组的最短无序子数组,左边界是由数组的无序部分的最小元素的位置决定的,右边界是由数组无序部分的最大元素的位置决定的。所以遍历数组,找到第一个降序开始的最小元素,然后从右开始找第一个升序开始的最大元素,接着找到他们的正确位置,输出长度。class Solution { public int findUnsortedSubarray(int[] nums) { if(nums==null || nums.length==0 || nums.length==1)return 0;原创 2021-01-19 17:42:54 · 107 阅读 · 0 评论 -
打乱数组
用构造函数初始化输出的数组。reset()返回这个数组的原态。shuffle()返回一个数组的打乱结果用的是Fisher-Yates 洗牌算法,要让数组的每个排列出现的概率一样,n个字符的数组有n!个排序,为了将这些顺序编码,就得log(n!)个字符时间复杂度为O(n),空间复杂度为O(n)来存储之前的数组。重排的步骤就是遍历数组,并生成一个当前下标到末尾的随机下标,然后将当前小标值和随机下标值交换。class Solution { int[] array; int[] orig原创 2021-01-19 16:53:07 · 60 阅读 · 0 评论 -
矩阵置零(原地变换)
将矩阵中0元素的行和列都变成0,如果正常做非常好做,只要遍历一遍记录0的位置,然后第二遍遍历将该行和列变成0即可。但这样需要用到空间复杂度为O(mn)时间O(m+n)第二种在找0 的过程中就把矩阵中的行和列都变成一个设置的值(不是0),第二遍遍历将这种值的位置都变成0,但这样每个0元素都会遍历m+n次,所以为O(mn)*(m+n)空间为O(1)第三种在找到0后将列首和行首的两个元素变成0,这样只需遍历两个即可给行和列赋值,不用重复赋值,但要注意第一行和第一列的第一个都是0,0,所以需要额外用一个变量标志原创 2021-01-19 13:26:34 · 1241 阅读 · 0 评论 -
双指针7.快乐数(快慢指针)
各位平方和趋于1的数为快乐数,也就是不断算一个数的各位平方和,最后的情况可能趋于三种情况,第一种是趋于1,第二种是不断循环,第三是趋于无穷大,其实的第三种永远不会发生,因为对于3位数的数来说,下一位永远不可能大于243,4位及以上的数每次都会丢失直到3位。所以只有两种情况。所以我们要先算这个数的平方和,然后判断这个数是否已经出现过了,用hashset来记录,但这样用的空间太多了,其实这样得到的是一个隐式链表,判断有没有环就用快慢指针。class Solution { public boolean原创 2021-01-16 09:38:03 · 102 阅读 · 0 评论 -
双指针6.接雨水(异向指针)42
接雨水与最多装水容器相比,最多装水容器可以直接计算出最多的,面积相对比较好算,而接雨水需要算每一个位置可以装的雨水,这个位置可以装的水为长乘宽,长为1,宽为最小减现在的y值。暴力需要双层循环O(n)如果存储左右的最大值,并且每移动一次都更新一次,则时间O(n),空间O(n)双指针:如果使用双指针从两边开始的话,在遍历的过程中就可以算到两边的可以接雨水的值,就可以省去在过程中的空间使用。class Solution { public int trap(int[] height) {原创 2021-01-15 18:49:50 · 51 阅读 · 0 评论 -
topk 5.前k个高频单词
套路就是普通的map和优先级队列的套路需要着重注意的是输出顺序需要是高频在前面,相同频率则输出字母顺序靠前的。则先按频率排序,再按照字母顺序逆序排序,但由于是小顶堆,所以输出的第一个其实是频率最低,字母顺序靠前的,所以需要逆序。import java.util.PriorityQueue;import java.util.HashMap;import java.util.ArrayList;import java.util.Collections;class Solution { pub原创 2021-01-11 13:47:53 · 155 阅读 · 1 评论 -
topk 4.有序矩阵中的第k个元素
如果是双层矩阵中找某个值,则可以从右上角开始找找第k个小的值,则可以利用归并来归并每一行多路归并有链表的多路归并,每次加入pq中一个节点,而数组其实也一样,每次加入一个三个值的数组,第一个值放现在到达的数组的值,第二个值放链表的顺序,第三个值放此矩阵中的值顺序。非常巧妙的方法。import java.util.PriorityQueue;import java.util.Arrays;class Solution { public int kthSmallest(int[][] matri原创 2021-01-10 23:19:02 · 178 阅读 · 1 评论 -
topk 3.前k个高频元素
也是维护一个堆,只不过比的条件是频率,所以事先需要用一个map来存数字出现的频率。import java.util.PriorityQueue;import java.util.HashMap;class Solution { public int[] topKFrequent(int[] nums, int k) { if(nums.length==0 || k==0){ return new int[0]; } Map原创 2021-01-10 19:02:53 · 102 阅读 · 0 评论 -
topk 2.数组中的第k个最大元素
1partitonimport java.util.Arrays;class Solution { public int findKthLargest(int[] nums, int k) { if(nums==null || nums.length==0){ return 0; } return quickSerch(nums,0,nums.length-1,k-1); } public int quic原创 2021-01-10 17:33:27 · 55 阅读 · 0 评论 -
把数组组合成最小的数
暴力解全排列,然后组成,最后输出最小的数。类似于字符串的全排列,那个题就是把排列过程分为第一个和后面的,可以通过递归实现,也可以转换为动态规划定义排序规则什么排序规则可以使得数最小,如果确定就可以在比较两个数的时候找到谁应该排在前面而不只是谁大,排序规则就是将m和n两个数字拼接成mn和nm,看哪个大则排序到前面,等于重新定义了排序规则那怎么比较每个str的组合呢,第一种就用普通的for循环嵌套比较就好。如果用java语言可以写比较器来比较(注意比较器只能用来比较集合,所以要把int数组变成Integ原创 2020-12-04 17:05:39 · 328 阅读 · 0 评论 -
判断是否为扑克牌顺子
判断一个数组是否是顺子把0当成大王,小王,可以替任何数字,判断输入的数组是否可以连着首先这个题数组的数字没有顺序,输入也没有规定,如果要在遍历一遍之后知道是否连着,需要一个额外的数组来确定他们的顺序并同时记录最大值和最小值。如果发现最大值和最小值之间相差会小于输入的长度(考虑的0的情况),说明是连着的。且不能有重复的(重复肯定不连着了)public class Solution { public boolean isContinuous(int [] numbers) { if原创 2020-12-12 17:30:39 · 289 阅读 · 0 评论 -
二分5.寻找两个排序数组的中位数
首先如果使用归并数组找到中间数,则空间复杂度为O(n),时间复杂度为O(n),如果利用一个指针来达到找中位数的过程,模拟归并但不归并,那时间复杂度仍为O(n)由于题中说了是有序的,所以可以尝试二分,这个题本质就是找到数组中第k小的数,k为(m+n)/2或者是(m+n)/2和(m+n)/2+1的平均值。先比较A[k/2-1]和B[k/2-1],若A[k/2-1]<B[k/2-1],则比A[k/2-1]小的数肯定不可能成为k,则直接排除掉A[k/2-1]以及比它小的,可以排除掉k/2的数字,并根据排除原创 2020-12-27 08:33:04 · 178 阅读 · 0 评论 -
双指针法5.删除数组中重复数字(同向指针)
利用双指针法,left来代表删除过后的数组指针,right代表遍历的指针,一次遍历即可完成更新。class Solution { public int removeDuplicates(int[] nums) { if(nums==null || nums.length==0)return 0; int left=0; int right=1; while(right<nums.length){ if(n原创 2020-12-23 13:32:34 · 344 阅读 · 0 评论 -
双指针4.三数之和/三数最接近之和/n数之和(异向指针)
输出一个数组中三个数加起来等于0的所有数组,不允许有重复。可以想到最简单的方式就是三层循环遍历所有的组合,但是这样会有重复,所以在遍历之前需要对数组排序,排序之后再开始遍历,如果发现一样则跳过。还可以发现第二层循环确定之后,其实第三层循环只有一个数需要确定,也就是j确定之后第三个数其实已经确定了,所以在每个j循环之前都定义一个变量在数组最右端,当此时三数相加不等于0时就three–,直到相加为0则j++,也就是j和three在确定i的情况下会遍历一遍数组。所以时间复杂度为O(n2)空间复杂度为O()。原创 2020-12-23 11:20:56 · 227 阅读 · 1 评论 -
双指针法3.装水最多的容器(异向指针)11
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器,且 n 的值至少为 2。思路就是双指针,从左右分别开始遍历,找较小的那个数,那个数最大的值最多只能是它自己了class Solution { public int maxArea(int[] height) { i原创 2020-12-23 09:31:30 · 58 阅读 · 0 评论 -
滑动窗口--长度最小的子数组209
给一个数组arr和一个正整数s,找出其中长度最短的大于s的子数组。分析这个题首先是连续子数组,可以用滑动窗口解决,最终要start到最后才结束遍历,所以可以用while循环,在每次end++后,都判断是否达到条件,达到条件则进入while循环来循环移动start直到不满足条件。最终输出最小的min。class Solution { public int minSubArrayLen(int s, int[] nums) { if(nums==null || nums.l原创 2020-12-18 12:41:43 · 124 阅读 · 0 评论 -
归并1.逆序对+小和问题(归并)
求一个数组的逆序对总数=求一个数右边有多少个数比它小逆序对就是一个数组中前面的值和大于后面的值的一组数。那么把数组分成前后两部分,分别进行归并,归并到最后merge两个数组,在这个过程中排序,并且计算出有多少个数是逆序的。这样到后来归并两个数组的时候,已经知道两个数组各自有多少逆序对了,只需要计算归并过程中产生的逆序对。因为已经是排序完的,所以找到第一个大于第二段中的值的时候,第二个值一定小于全部的第一段中的值,所以count要加上第一段中的剩下的所有数据。注意两点1.进行移位操作的时候一定记得加上原创 2020-12-08 19:04:17 · 102 阅读 · 0 评论 -
位操作2.数组中数字出现的次数
数组中只出现一次的两个数字除了这两个数字外其他都出现了两次,找到这两个数字要求空间复杂度为O(1),时间复杂度为O(n)如果只有一个只出现一次的数字,首先根据异或的性质,任何一个数字异或它自己都等于0,所以从头到尾依次异或之后就会出现最终那个只出现一次的数字。所以现在的思路是将数组拆成两份,一份包含一个只出现一次的数组,这样就可以按照上面的思路来做了。我们还是异或一遍,得到的结果就是两个数字的异或结果,这两个数字不一样,所以一定不是0.至少有一位为1,然后找到这个数字中第一个为1的位置,计为第n位原创 2020-12-10 11:05:24 · 118 阅读 · 0 评论 -
位运算 1.计算1的个数
求二进制中数的1的个数思路1:(1)正常思路是用数来与1与,如果是的话就是1,count++,将数向右移位直到0,但这样如果输入负数会给高位补1,那样会陷入循环(可以用>>>)>>>是逻辑移位符,即使是负数向右移动也是补0.(2)既然不能动数,那就动1,将数字向左移动,这种思路有几位就要移动几次(3)还有一种思路是有几个1就移动几次,利用n&n-1,这样会使得最右边的1变成0,就相当于把左边的第一个1移动到最右边来,也就算做有一次1。如果最右边不是1,那原创 2020-11-13 09:38:17 · 584 阅读 · 0 评论 -
遍历2.转圈打印矩阵/奇怪的输出矩阵
转圈打印矩阵以对角线为参考,也就是知道两个点,把四个点的坐标都标出来。然后从第一个点到右边的得点打印一圈,将两个对角同时变小,但这样的结果是如果到最后四个点都一样也就是最中间的一个点时没法打印,所以采用的是用方法循环调用另一个方法,这样的好处是每次进入方法都可以判断a是否等于c,在else if里放b是否等于d,else里放其他的正常打印一圈,这样只会执行一个里面的方法,不会重复也不会漏掉。还有一个需要注意的就是定义的时候(a,b)(c,d)指的是矩阵中的四个点,但不能把它放在坐标系中处理而应该放在矩阵原创 2020-11-25 16:09:35 · 134 阅读 · 0 评论 -
遍历1.二维数组中的查找
二维数组的查找一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。我的做法就是最优解:即从右上角开始找直到超出界限。 public class Solution { public boolean Find(int target, int [][] array) { int a=array.length;//行数 int b=a原创 2020-10-30 08:32:10 · 166 阅读 · 0 评论 -
排序2.复杂排序
堆排序堆排序是一种选择排序,遍历后选择数组中最大的值放到堆顶,可用数组实现,最好和最坏和平均复杂度都为O(nlogn),不稳定。堆就是一种完全二叉树,排序特征是堆顶元素大于子元素(不管子元素之间的排列);完全二叉树的特征是层序遍历等于满二叉树的层序遍历(也就是底层可以没有右边的子树)用数组来描述堆的定义有大顶堆和小顶堆,若为大顶堆,则i的父节点为i/2,子节点为2i和2i+1arr[i]<arr[i/2] && arr[i]>arr[2i] && arr[原创 2020-12-02 21:13:32 · 447 阅读 · 0 评论 -
排序1.简单排序
排序可分为内排序和外排序内排序针对的是小数组,在内存中完成外排序针对的是多个文件,在外存中完成简单排序的复杂度普遍是O(n2)冒泡排序冒泡的意思就是小的数从下面浮上去,也就是从最后一个开始j与前面的j-1比较,直到比较到i。直到执行完一轮之后,第一个数就是全数组最小的数。执行n-1轮即可完成排序.i表示的是排序好的位置,j表示的是此轮比较的位置。算法的复杂度稳定为O(n),排序不稳定,如果定义相同不交换则稳定 public void sort(int[] arr) { for(原创 2020-12-02 09:25:37 · 121 阅读 · 0 评论 -
双堆1.数据流的中位数
数据流中的中位数有一个数据流一直输入字符,用insert方法插入数据,用另一个方法获得中位数。这个题的做法就是构建堆结构,一个为最小堆,一个为最大堆,因为数组的长度是变化的,所以直接用优先级队列吧。插入之后保证最小堆的数全部大于最大堆,且两边数目不能相差超过1。所以如果现在个数为偶数,则下一个插入最大堆,那怎么保证此时插入的数据小于全部的最小堆呢,就是先把数据插入最小堆,返回堆顶之后再插入最大堆。如果此时个数为奇数,说明上一个一定插入的是最大堆,则现在要插入最小堆,怎么做和上面类似获得中位数的时候就是原创 2020-12-03 12:37:03 · 138 阅读 · 0 评论 -
Topk/k-th1.找到数组中最小的k个数
找到数组中前k个小的数第一想法是排序,排序之后返回前k个,这种做法的复杂度为O(nlogn)partition利用第k个数字来partition,首先将比这个数字小的数字放到左边,把大于它的数字放到右边,则现在看左边有几个数字,如果大于k,则再次partition,如果小于k,则也partition,循环直到i为k-1.此时的前k个数就是最小的k个数。import java.util.ArrayList;public class Solution { public ArrayList&l原创 2020-12-02 22:30:26 · 120 阅读 · 0 评论 -
partition3.找到数量超过一半的数字
找到数量超过一半的数字如果没有返回0.统计一个数字出现的次数,最简单的想到的就是排序,排序算法的复杂度为O(logn)。所以这个题肯定是根据数组本身特点来做,一个数超过一半,则说明排好序之后这个数一定在数组中间。出现的次数比其他数字出现的次数加起来还要多。所以设置两个变量,一个保存数字,一个保存次数。遍历时,如果它与之前的数字相同则次数加1,不相同则次数减1.若次数为0,则保存下一个数字并将次数变为1.这样的话遍历完之后这个数字一定是出现最多的。public class Solution {原创 2020-11-29 16:19:23 · 470 阅读 · 0 评论 -
partition 2.不改变数组位置使得数组奇数位于偶数前
奇数放在偶数前且保证数之间的相对位置不变类似于快排的partition问题,快排要分为小于大于,等于三个部分,所以需要两个变量less,more来分开,还有一个是cur。而这要分为奇数偶数,需要一个变量mid,还需要cur。快排一直让less和more处于分界处。而这个只有一个变量的时候可以先让mid走几步,走到偶数的地方,让它表示第一个开始的偶数,然后cur再等于它的下一个,开始循环。如果此时是偶数就跳过,是奇数(此时要把这个数插入到mid之前的一个位置,把mid到这个数之间的数全都后移)则将cu原创 2020-12-17 13:10:43 · 132 阅读 · 0 评论 -
双指针法2 调整数组顺序使奇数位于偶数前面(异向指针)
奇数放在偶数前1.最基本的思路就是扫描数组,碰到偶数则把所有的数前移,把这个偶数放在最后一个,这样的复杂度是O(n2)2.第二种思路是只要碰到偶数就将它与一个奇数交换,用两个指针分别指向开头和结尾,然后开始移动,如果前一个是偶数,后一个是奇数,则交换,如果前一个是偶数,后一个也是偶数,则移动后一个向前。若前一个是奇数,后一个也是奇数,则移动前一个向后。这种做法的复杂度就是O(n),因为遍历一次,每个数也只操作了一次。3.然后可以写一个有扩展性的第二个代码,也就是将奇数和偶数判断这个流程封装成一个函数,原创 2020-11-20 15:12:50 · 207 阅读 · 0 评论