![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
文章平均质量分 67
rotk2015
这个作者很懒,什么都没留下…
展开
-
反转链表、递归、迭代
首先是经典的LeetCode206,反转整个链表。解法可分为迭代、递归两种方式。而递归解法,根据返回函数的先后顺序(即处理当前递归栈与下一递归栈的先后顺序),又可分为top-down,bottom-up两种方式。本题十分经典,仔细体会,可以加深对迭代、递归的理解。public ListNode reverseList(ListNode head) { // return iterateSolution(head); // return recursionTopDownSolution(..原创 2021-08-06 16:06:52 · 159 阅读 · 0 评论 -
LeetCode_String to Integer (atoi)
LeetCode第8题,字符串转整型。为什么不用一个大循环而选择用分段式的小循环?合法字符串的格式是分段式的,但问题是,我们不知道实际的字符串的各个段长度为多少(无法定界)。若使用一个大循环轮询处理,需要额外的状态变量与判断语句决定当前状态,代码逻辑会变得更加复杂。如何进行溢出判断?这个问题是写本文的主要动机,我们可以很直接的得到一个可读性很高的、同时也是高赞答案采用的方式:if(total>Integer.MAX_VALUE/10 || (total==Integer原创 2021-07-03 16:02:55 · 86 阅读 · 0 评论 -
算法心得-未完待续
处理有序数组时,先考虑双指针(对撞指针,快慢指针)。形参引用类型,先考虑形参是否为 null 吧。接2,迭代链表时,不要随便就 cur.next.next,你考虑过 cur.next 是null吗?接3,如果不想考虑 null,可以试着新维护两个头、尾结点。能用 for 别用 while。接5,头铁非要用 while,别在结束循环判定条件里更新控制变量!!!不简洁但一眼就能看明白的代码,要优于那些形式上简洁但不直观的(不要为了简洁优雅而耗费时间,有那功夫想想性能咋提高吧)。...原创 2021-06-05 12:04:07 · 106 阅读 · 2 评论 -
LeetCode_Partition Equal Subset Sum
416题,给定某无序数组,判断其是否能被分成总和相等的两个子集。此问题可转换成:判断其是否能恰好凑出原数组总和的一半,即 0/1 背包问题。那么可以由此引出两个优化点:若想能凑出,则原数组总和必为偶数,且数组内最大元素不能大于原数组总和一半。此外便是常规的二维数组压缩至一维的dp套路:class Solution { public boolean canPartition(int[] nums) { int sum = 0; int max = 0;..原创 2021-03-28 10:04:34 · 68 阅读 · 0 评论 -
LeetCode_Next Permutation
字典序全排列问题,该系列的核心问题是,如何从一个字典序的排列生成下一个最小排列。例如,12543 的下一个最小排列是,13245。我们可以这么考虑,排列从左到右的每个数位,对应不同的权重。其中,最左边的权重最大,最右的权重最小(右至左如同个、十、百、千…);而给定的数字,如同砝码。那么这个问题翻译过来就是,生成下一个总重量大于当前重量的排列,且该排列在所有可能的结果中,总重量最小(说白了就是重一点意思一下得了)。那么,给定数字 1 2 3 4 5,它的所有排列中,最小的、最大的分别是什么?这..原创 2021-03-22 19:48:08 · 111 阅读 · 0 评论 -
ArrayDeque部分源码剖析
笔者所用JDK为RedHat的OpenJDK 8u282 win64版。简介ArrayDeque,数组实现的双端队列。核心思想是维护头尾指针,将数组变为循环数组,由于没有固定的起始参考量(头指针可动),故无法按索引取值。但是,相比于...原创 2021-03-19 19:53:15 · 108 阅读 · 0 评论 -
二分查找——一网打尽所有细节!
二分查找,典中典的算法,笔者先写下经典实现。代码如下:参考资料:详解二分查找算法。原创 2021-03-15 22:04:28 · 62 阅读 · 0 评论 -
JAVA除2与右移
起因是二分查找取mid值时,是这么写的int mid = lef + (rig-mid)/2;但还有兄弟抠细节,将 除2 换成 右移,因为位运算快。。。int mid = lef + (rig-mid)>>1;抛开效率不谈,除2 和 右移 一样吗?笔者搜索了一番,得出结论:对于负奇数而言,如-3,除2得到 -1,而右移则得到 -2。除此之外,除2 和 右移 结果是一致的。原因:奇数除2会得到小数,赋给 int 类型时,只保留整数部分,因此,无论正数还是负数,除..原创 2021-03-14 18:52:53 · 1397 阅读 · 0 评论 -
快速排序——凑活能用版
快速排序是排序的经典算法,具体思路很简单,但实现起来并非那么容易!如果使用最直观的双指针法,总会遇到神奇的问题:low<high 还是 low<=high?!(我纠结一天了真的整不明白orz…)所以为了珍爱生命,以后就用挖坑填数法吧。。。代码如下:import java.util.Arrays;public class QuickSort { public static void sort(int[] input, int low, int high){ ..原创 2021-03-14 15:37:22 · 80 阅读 · 0 评论 -
LeetCode_The Skyline Problem
自己的一开始的想法将 x 轴抽象成一个数组,然后遍历一次建筑群,每遇到新一个建筑,就更新对应的子数组高度。最后将整个数组再遍历一次即可。这个思路很简单,但是存在一个问题,就是维护的数组长度,与建筑群的总占地宽度与要求的输出精度相关,这样在极端条件下,可能会造成很大的空间浪费。同时,这种做法在最后遍历数组时,我们可以发现,有大量的重复数组值是无用的。后来看了下评论区和网上的资料,得到一个比较好的方案。仔细观察可以发现:天际线的 key point 由建筑的边界构成。而建筑之间经常会有覆盖现象,..原创 2021-03-04 15:55:25 · 82 阅读 · 1 评论 -
LeetCode_Construct Binary Tree from Inorder and Postorder Traversal
给定二叉树中序、后序遍历结果,构建二叉树。后序的最后一个结点必为根节点。对于后序的最后一个结点而言,中序遍历结果中,位于它左边的是它的左子树,位于它右边的是它的右子树。由 2 可得基本递归思路一:不断利用后序最后一个节点将中序结果分割,自底向上递归建立左右子树即可。此时,由于要在中序结果中寻找后序最后结点,故要么每次都循环遍历(时间代价),要么提前建立一个哈希表(空间代价)作为参数。本文的重点是第二种递归思路,既不循环也不需要哈希表。代码如下:int pInorder; // index o原创 2021-02-03 15:56:42 · 147 阅读 · 0 评论 -
浅谈迭代(非递归)遍历二叉树
不管是迭代遍历还是递归遍历,二叉树遍历都只做了三件事:处理左子树,处理右子树,处理当前结点。依据处理当前结点的时机不同,可分为:先序、中序、后序三种遍历方式。二叉树迭代遍历的主要难点在于:如何在处理完子树后,返回父结点。常用思路是利用栈先入后出的特性。原创 2021-01-23 17:24:16 · 275 阅读 · 1 评论 -
经典算法题——寻找质数
本题也算是老生常谈了,给定一个数,输出小于该数的素数个数。暴力解法是遍历。当然,主要想说的是其优化方法。素数,即仅能被拆分成1与自身二数乘积的数。若有其它的拆解方法,则为合数。考虑拆分成乘积时,总是一个大数乘小数,那么我们并不需要遍历所有,仅需将范围限定在开根号后的范围内。合数总能拆解为两个素数之积(算数基本定理),故反向思考下,可以不用遍历除的方式判定,而是先将2的倍数筛去(必为合数),之后,3未被筛去,说明小于3的所有数都无法整除3,则3为素数,再将3的倍数筛去,如此循环往复,依次筛去剩余数原创 2020-12-28 20:50:11 · 384 阅读 · 0 评论 -
LeetCode_TwoSum
LeetCode题目TwoSum直接双重循环暴力解决,时间On2O_{n^2}On2,空间O1O_{1}O1。每次都要遍历查找,因此可以通过空间换时间,缩短查找的时间开销,先遍历一次建立散列表(HashMap),再遍历一次利用散列表查找,时间OnO_{n}On,空间OnO_{n}On。(此外还有HashTable,HashSet)public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map原创 2020-12-28 19:46:45 · 70 阅读 · 0 评论 -
算法——快慢指针迷思
今天学了快慢指针算法,思想很简单,不过有个困扰点:为什么两个指针一定会在某时刻相遇?我当然知道追及问题,问题是这里不是连续移动直至经过(或追及),指针的移动方式是离散的,如何保证两指针一定会恰好在某个结点相遇?具体的例子:快指针4,慢指针2,环路长4,假定两指针并非同起点出发(为了说明问题假设有此条件),快指针在环路起点时,慢指针恰在前一个位置。入环后,快指针速度恰等于环路长,故原地不动;而慢指针,恰在快指针左右来回摇摆,不得相遇。在网上搜索了下,找到了满意的答案。简单来讲,由于两指针.原创 2020-12-23 22:25:45 · 140 阅读 · 0 评论