思路:在包含问题的解空间中,按照深度优先搜索的策略,从根节点出发深度探索解空间树,当探索到某一节点时,先判断该节点是否包含问题的解,如果包含,就从该节点触发继续探索下去,如果不包含该节点的解,则逐层向其祖先节点回溯...示例 组合总和:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。...candidates 中的数字可以无限制重复被选取。 说明: 所有数字(包括 target)都是正整数。 解集不能包含重复的组合。...可以做如下初步分析: 可以无限制重复被选取,比如4个2满足条件 要找到所有的组合,也就是说要穷尽的去探索所有可能的情况 当数据本身大于8或者和已经超过8则没有必要对接下来的数据做继续探索了 参照回溯法的思路...:按照深度优先的规则,这里对“深度”的定义则是从第一元素开始,因为它可以被无限制的选取,那么就可以一直累加知道它会超过目标值,然后进行回溯 image.png 去掉了超过目标值的节点 优先选取第一个元素进行重复获取
今天就从最最常用的 ArrayList 说起。 概述 ArrayList 是一种可以动态增长和缩减的线性表数据结构,允许重复元素,允许 null 值。...所以,如果我们构建了一个空 ArrayList,当我们添加第一个元素的时候,就会默认扩容至 10 。...fastRemove(index); return true; } } return false; } 这里要注意一点,当集合中存在重复元素时.../** * * @param c 集合 * @param complement 为 true 时,保留指定集合中的值,为 false 时,删除指定集合中的值 * @return 数组中重复的元素都会被删除...: 基于动态数组实现,自动扩容每次增长为原来的 1.5 倍 在内存中是连续的,具备随机访问能力 根据下标获取元素的时间复杂度是 O(1) 添加元素和删除元素的平均时间复杂度是 O(n) 允许重复元素,允许
而本篇最重要和基础的就是要掌握这两种方法实现的无重复全排列,其他的都是基于这个进行变换和拓展。 全排列问题 全排列,元素总数为最大,不同是排列的顺序。...回溯算法用来解决搜索问题,而全排列刚好也是一种搜索问题,先回顾一下什么是回溯算法: 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回...具体的试探策略如下: 从待选集合中选取第一个元素(共有n种情况),并标记该元素已经被使用不能再使用。...当所有元素被标记后,顺序收集被标记的元素存储到结果中,当前层递归结束,回到上一层(同时将当前层标记的元素清除标记)。这样一直执行到最后。...这样当递归进行到最后一层的时候就将数组的值添加到结果集中。如果不理解可以参考下图进行理解: ?
在快速排序中,切分元素的选取很关键,通常我们可以选取输入数组的第一个元素作为切分元素,然后把它交换到数组中的合适位置使得它左边的元素都小于等于它,右边的元素都大于等于它,而后对其左右两边的子数组递归执行切分过程...首先在第6行中,我们选取了数组的首元素作为切分元素并将它保存在变量p中,然后在第7行进入一个无限循环中。...此时i的值为第一个大于等于p的元素的索引或是high的值,若为high的值则表示数组中不存在大于等于p的元素。...此时j的值为第一个小于等于p的元素的索引或是low的值,若为low的值则表示数组中不存在小于等于p的元素。 接下来,执行第24行的if语句判断i和j的大小,若i >= j, 会跳出无限循环。...第四种情况:数组中既不存在大于等于p的元素,也不存在小于等于p的元素,这意味着数组中的所有元素都等于p。那么此时经过两个内层循环后,i的值为high,j的值为low。
它的实现方式是每次从序列中选出一个基准值,其他数依次和基准值做比较,比基准值大的放右边,比基准值小的放左边,然后再对左边和右边的两组数分别选出一个基准值,进行同样的比较移动,重复步骤,直到最后都变成单个元素...,再将 mark 所在位置的元素和遍历到的元素交换位置,mark 这个位置存储的是比基准值小的数据,当遍历结束后,将基准值与 mark 所在元素交换位置即可。...重复步骤,直到左右两个指针相遇,再将基准值与左侧最右边的元素交换。...既然堆顶元素永远都是整棵树中的最大值,那么我们将数据构建成堆后,只需要从堆顶取元素不就好了吗? 第一次取的元素,是否取的就是最大值?...所以我们取排名的时候应该特别注意,原数组中的数据要从右往左取,从 countArr 取出排名后要把 countArr 中的排名减 1 ,以便于再次取重复数据的时候排名往前一位。
希尔排序6 比较完之后的效果是 7,8,12 三个数为有序排列。 ? 希尔排序7 当最后一个元素比较完之后,我们会发现大部分值比较大的数据都似乎调整到数组的中后部分了。...希尔排序9 重复步骤,即可完成排序,重复的图就不多画了。 我们可以发现,当区间为 1 的时候,它使用的排序方式就是插入排序。...,再将 mark 所在位置的元素和遍历到的元素交换位置,mark 这个位置存储的是比基准值小的数据,当遍历结束后,将基准值与 mark 所在元素交换位置即可。...重复步骤,直到左右两个指针相遇,再将基准值与左侧最右边的元素交换。...既然堆顶元素永远都是整棵树中的最大值,那么我们将数据构建成堆后,只需要从堆顶取元素不就好了吗? 第一次取的元素,是否取的就是最大值?
最坏情况:如果待排序元素中第一个元素最大,其余元素从小到大排列,则仍然需要进行 n * (n - 1) / 2 次比较,且每趟排序都需要移动 3 次元素,即移动元素的次数为3 * (n - 1)次。...具体算法描述如下: 1)从第一个元素开始,该元素可以认为已经被排序; 2)取出下一个元素,在已经排序的元素序列中从后向前扫描; 3)如果该元素(已排序)大于新元素,将该元素移到下一位置; 4)重复步骤...下面提供几种常用的快排优化: 优化一:随机基准 每次随机选取基准值,而不是固定选取左或右边界值。将随机选取的基准值和右边界值进行交换,然后就回到了之前的解法。...优化四:三路划分 如果待排序列中重复元素过多,也会大大影响排序的性能,这是因为大量相同元素参与快排时,左右序列规模相差极大,快排将退化为冒泡排序,时间复杂度接近O(n2)。...② 算法描述 1)找出待排序的数组中最大和最小的元素; 2)统计数组中每个值为 i 的元素出现的次数,存入数组C的第i项; 3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
1.直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列。...再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。 重复第二步,直到k=1执行简单插入排序。 ? 如何写成代码: 首先确定分的组数。 然后对组中元素进行插入排序。...a[j + d] = temp; } } } } 3.简单选择排序 常用于取序列中最大最小的几个数时...将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。 比对完成后,将最小的值与第一个数的值交换。 重复2、3步。...将序列中所有元素两两比较,将最大的放在最后面。 将剩余序列中所有元素两两比较,将最大的放在最后面。 重复第二步,直到只剩下一个数。 ? 如何写成代码: 设置循环次数。
如果第一个比第二个大,就交换它们两个; 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数; 针对所有的元素重复以上的步骤,除了最后一个; 重复步骤1~3,直到排序完成...算法描述 从第一个元素开始,该元素可以认为已经被排序; 取出下一个元素,在已经排序的元素序列中从后向前扫描; 如果该元素(已排序)大于新元素,将该元素移到下一位置; 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置...快排有个问题,基准的选择对效率的影响很大,极限情况下你每次都选最大的,效率就很差了.可以通过随机选取基准的方法略微的规避一下这个问题....学习心得 堆排序的难点其实不在排序上,而在与堆上.] 如何构造一个最大(最小堆)? 移除堆顶元素后如何调整堆?...算法描述 找出待排序的数组中最大和最小的元素; 统计数组中每个值为i的元素出现的次数,存入数组C的第i项; 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加); 反向填充目标数组:将每个元素
本篇内容包括:ArrayList 概述、ArrayList 的扩容机制(包含源码部分)、如何在遍历 ArrayList 时正确的移除一个元素、ArrayList 的构造方法及常用方法、关于 Array...数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。...当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。...假设按照从 0 到 size-1 下标来删有相邻且相同的两个元素,删除第一个,数组长度会 -1 并且所有元素往前移动一位,那么第二个就到第一个元素的位置,此时控值 for 循环的下标 i 已经 +1 ,...o) 此方法从该列表中删除指定元素的第一个匹配项(如果存在) void clear() 此方法将从此列表中删除所有元素 Object clone() 此方法返回此ArrayList实例的浅表副本 boolean
将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列。 对第四个数、第五个数……直到最后一个数,重复第二步。 ?...再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。 重复第二步,直到k=1执行简单插入排序。 ? 如何写成代码: 首先确定分的组数。 然后对组中元素进行插入排序。...a[j + d] = temp; } } } } 3.简单选择排序 常用于取序列中最大最小的几个数时...将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。 比对完成后,将最小的值与第一个数的值交换。 重复2、3步。...将序列中所有元素两两比较,将最大的放在最后面。 将剩余序列中所有元素两两比较,将最大的放在最后面。 重复第二步,直到只剩下一个数。 ? 如何写成代码: 设置循环次数。
文章,每日送达 ---- 1.直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列。...再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。 重复第二步,直到k=1执行简单插入排序。 ? 如何写成代码: 首先确定分的组数。 然后对组中元素进行插入排序。...} a[j + d] = temp; } } } } 3.简单选择排序 常用于取序列中最大最小的几个数时...将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。 比对完成后,将最小的值与第一个数的值交换。 重复2、3步。...将序列中所有元素两两比较,将最大的放在最后面。 将剩余序列中所有元素两两比较,将最大的放在最后面。 重复第二步,直到只剩下一个数。 ? 如何写成代码: 设置循环次数。
将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列。 对第四个数、第五个数……直到最后一个数,重复第二步。...再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。 重复第二步,直到k=1执行简单插入排序。 如何写成代码: 首先确定分的组数。 然后对组中元素进行插入排序。...a[j + d] = a[j];//向后移动d位 } a[j + d] = temp; } } } } 3.简单选择排序 常用于取序列中最大最小的几个数时。...将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。 比对完成后,将最小的值与第一个数的值交换。 重复2、3步。...将序列中所有元素两两比较,将最大的放在最后面。 将剩余序列中所有元素两两比较,将最大的放在最后面。 重复第二步,直到只剩下一个数。 如何写成代码: 设置循环次数。
01 流如何简化代码如果有一个需求,需要对数据库查询到的菜肴进行一个处理:筛选出卡路里小于 400 的菜肴对筛选出的菜肴进行一个排序获取排Java8 的新特性主要是 Lambda 表达式和流,当流和 Lambda...这类操作都是惰性化的,仅仅调用到这类方法,并没有真正开始流的遍历,真正的遍历需等到终端操作时,常见的中间操作有下面即将介绍的 filter、map 等 终端操作 一个流有且只能有一个终端操作,当这个操作执行后...,因为内部进行优化的原因,当找到第一个满足大于三的元素时就结束,该方法结果和 findFirst 方法结果一样。...,因为内部进行优化的原因,当找到第一个满足大于三的元素时就结束,该方法结果和 findFirst 方法结果一样。...0,一个 BinaryOperator accumulator 来将两个元素结合起来产生一个新值,另外, reduce 方法还有一个没有初始化值的重载方法获取流中最小最大值通过 min/max 获取最小最大值
,可以添加或删除元素 它的特点就是读速度、更新快,增删慢;内存相邻,根据Index读取的时间复杂度是O(1);可以存储重复元素,但线程不安全 ArrayList 的扩容机制 //ArrayList openJDK...不存在则报错 ArrayList 和 LinkedList 使用场景 频繁访问列表中的某一个元素,或者需要在列表末尾进行添加和删除元素操作,用ArrayList 频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作...中的数据是无序的,可以放入 null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束 HashSet 是基于 HashMap 算法实现的,其性能通常都优于TreeSet 为快速查找而设计的...BlockingQueue BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。...当生产者线程调用put之类的方法加入元素时,会触发 Delayed 接口中的compareTo方法进行排序 消费者线程查看队列头部的元素,注意是查看不是取出。
其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。...请简述迭代器的实现原理 当遍历集合时,首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出...Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,在调用Iterator的next()方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后...,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历... list) { //定义变量存放年龄 int a = 0; //定义变量存放最大年龄的索引值 int index =
8.一个整数List中取出最大数(找最大值)。不能用Max方法。 9. C#异常类返回哪些信息? 10. 如何创建一个自定义异常? IList 接口与List的区别是什么?...2.泛型的主要约束和次要约束是什么? 当一个泛型参数没有任何约束时,它可以进行的操作和运算是非常有限的,因为不能对实参进行任何类型上的保证,这时候就需要用到泛型约束。...List:在数组和ArrayList基础上优化,存储通用类型数据列表。优点:可扩展示,初始化无需指定长度,可插入指定位置数据 5. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?...6.有50万个int类型的数字,现在需要判断一下里面是否存在重复的数字,请你简要说一下思路。...数组没有length()这个方法,有length的属性。String有有length()这个方法。 8.一个整数List中取出最大数(找最大值)。不能用Max方法。
领取专属 10元无门槛券
手把手带您无忧上云