- 博客(187)
- 收藏
- 关注
原创 链表 - 【删除所有重复的元素】
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。解题思路这道题和83. 删除排序链表中的重复元素不一样的是,不保留重复元素,重复元素全部删除。所以,如果所有元素全部相同,最终返回的链表可能是空。对于这种问题,可以构造一个哑节点指向链表头节点;由于这道题是删除所有重复元素,所以遍历的区间必然至少有两个元素才可能有重复元素;假设当前遍历区间cur到尾节点,那么必然循环的条件是cur->next和cur->next->next都不等于空
2022-07-11 15:35:00
850
1
原创 源码阅读 - [Masonry]
源码结构分析Masonry是一个用于自动布局的第三方框架,可以很方便的给UIView添加布局约束,从而进行自动的布局;底层的基础APIMasonrys是在NSLayoutContraint上的基础上进行封装的,接下来先看下Constraint的使用:使用示例假设有superView和subView两个view,将subView添加到superView上,给这两个view添加约束,使这两个view在左上角重合,subView的宽高都为50; //创建superView UIView *super
2022-04-25 23:32:21
267
原创 内存管理 - [ARC、AutoreleasePool]
问题出发我们知道,在面向对象编程中,每个对象都存在对应的构造函数和析构函数,当对象被创建和销毁时,构造、析构函数会被分别调用。对象从创建到销毁的整个过程,称之为对象的生命周期,为了保证在(1)使用对象时对象是有效的,没有被过早释放;(2)不需要使用对象时,对象被正常销毁而不是一直驻留在内存中,我们需要对象的生命周期进行管理。那么在iOS系统中,对象生命周期管理策略是怎样的呢?为了更好地逐步的了解iOS的内存管理机制,先抛出一些问题:(1)iOS使用引用计数来管理对象的生命周期,什么是引用计数?(2)
2021-09-14 19:51:45
273
原创 UI -[渲染原理] -界面渲染那些事
当你被问到下面问题,你能够回答出来么?1、app从点击屏幕到完成渲染,中间发生了什么?2、当一个UIImageView添加到视图后,内部是如何渲染到手机上的?3、一个tableView中有多个cell,如何避免卡顿。今天,我们就来了解iOS中的渲染过程;图像渲染流水线图像渲染流程粗粒度地大概分为下面这些步骤:上述图像渲染流水线中,除了第一部分 Application 阶段,后续主要都由 GPU 负责,为了方便后文讲解,先将 GPU 的渲染流程图展示出来:上图就是一个三角形被渲染的过程中,
2021-08-03 23:06:33
604
原创 UI - [事件响应链] -响应链以及不能响应的控件什么时候抛弃事件
场景实例在controller的根view上有两个view, 分别为红色和蓝色,其中蓝色的view为红色的view的子view,现在希望扩大蓝色view的点击区域,在点击红色view中的非蓝色区域,蓝色区域也能响应。设计实现这个该怎么做呢?实际上是需要扩大蓝色view的响应区域。这里牵扯到响应者对象,什么是响应者响应者对象在iOS中,不是任何对象都能响应事件,只有继承自UIRespone的对象才可能可以接受并响应事件,我们称之为"响应者对象"。UIApplication、UIWindow、U
2021-04-29 17:45:28
475
2
原创 leetcode - [哈希表] - 数组中缺失的第一个正整数(41)
1、问题描述给定一个无序数组,求数组中缺失的第一个正整数。示例1:输入:[1,2,3,4]输出:5示例2:输入:[-1, 2, 5, 3]输出:1示例3:输入:[5,7,8,9]输出:12、解题思路分析:最小的正整数为1,所以可以查找数组,看1是否存在;如果存在,则看2是否存在于数组中;如果存在,再看3是否存在于数组中;一直循环下去,直到iii不存在于数组中,那么此时iii就是缺失的最小正整数。那么,需要查找的正整数iii最大为多少呢?假设数组的长度为lenlenlen
2020-05-12 00:08:15
196
原创 leetcode - [动态规划] - 打家劫舍
1、问题描述假设你是一个小偷,计划盗窃沿街的房屋,每个房屋都藏有一定数量的现金,影响你盗窃的唯一制约是每两间相邻的房屋装有相互连通的报警装置,如果你盗窃了两间相邻的房屋就会触发报警装置。给定一个非负整数数组表示每个房屋藏有的现金金额。计算在不触动报警装置的情况下,能盗窃到的最大金额。例子1:输入: [1,2,3,1]输出: 4解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3...
2020-04-15 00:07:51
298
原创 通用算法 - [博弈论] - 双人取数游戏
1、问题描述给定一个数组nums,a、b两人轮流从数组的左端或右端取一个数作为自己的得分,假设两人足够聪明,都采用最优的策略取数,且a先取,问a能能拿到的最大的分数是多少?示例:输入:nums=[4,7,5,3]输出:10解释:a能拿到的最大分数为7+3=10.2、解题思路分析:由题意,我们可以明确以下几点:(1) 当选手aaa、bbb在子数组nums[i,...,j]nums...
2020-04-06 17:51:46
2689
2
原创 通用算法 - [数组算法] -数组的前缀和
1、前缀和介绍对于一个数组AAA,我们新建一个长度相等的数组BBB,新数组中的每一项B[i]B[i]B[i]表示的是数组AAA的前iii项和,即前缀和:BBB中的每一项B[i]B[i]B[i]保存A[0,1,...,i]A[0,1,...,i]A[0,1,...,i]的和;类似的概念还有:后缀和:BBB中的每一项B[i]B[i]B[i]保存A[i,i+1,...,n−1]A[i,i+1,....
2020-04-06 15:44:29
1302
原创 leetcode - [动态规划] -最大正方形(221)
1、问题描述在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。示例:输入:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 42、 解题思路思路1:暴力法。对于矩阵中的每个元素,求以其为左上角顶点,可得到的最大正方形。这种方法的时间复杂度为O(N2M2)O(N^2M^2)O(N2M2),遍历每个元素需要O(N...
2020-04-04 00:59:52
322
原创 leetcode - [动态规划] -最大加号标志(764)
1、问题描述在一个大小在(0,0)到(N-1,N-1)的2D网格grid中,除了mines给出的单元格为0,其他单元格都为1。网格中包含1的最大轴对称加号的阶是多少,返回最大轴对称加号的阶。如果不存在轴对称加号,则返回0.一个k阶轴由1组成的轴对称加号指的是具有中心网格grid[x][y],以及从中心向上、向下、向左、向右延伸,长度为k-1,由1组成的臂,下面给出 k" 阶“轴对称”加号标志的...
2020-04-04 00:02:00
203
原创 leetcode - [栈、动态规划] - 最大矩形(85)
1、问题描述给定一个只包含0、1的二进制二维矩阵,找出只包含1的最大矩形,并返回其最大面积。示例:输入:[[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]输出: 62、解题思路思路1:暴力法。列举所有以(x1,y1),(x2,y2)(x_1,y...
2020-04-03 23:11:48
337
原创 leetcode - [栈] -柱状图中的最大矩形(84)
1、问题描述给定n个非负整数,用来表示柱状图中每个柱子的高度。每个柱子彼此相邻,且宽度为1.求柱状图中能勾勒出的最大面积。以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。2、解题思路方法1:暴力法。在柱子iii和柱子jjj构成的区间中,最大的矩形面积为区间长度*区间内最矮柱子的高...
2020-04-03 17:48:20
131
原创 leetcode - [DP、栈、双指针] - 接雨水(42)
1、问题描述给定n个非负整数,每个整数表示一个宽度为1的柱子的高度,将这n个柱子并排放在一起,问按这种方式排列得柱子在下雨时能接多少雨水。上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。示例:输入: [0,1,0,2,1,0,1,3,2,1,2,1]输出: 62、解题思路解决这道问题有...
2020-03-29 22:37:08
126
原创 通用算法 -[二分查找] - 细节问题
1、二分查找的若干细节问题二分查找的思路很简单,但是却有很多问题需要注意,比如:(1) while循环条件中什么时候是<=,什么时候是<?(2) middle什么时候加1,什么时候不加1?(3)当不存在查找的数时怎么处理?2、细节问题的解释针对以上问题,下面这篇文章很好的解释了这些细节问题:文章:详解二分查找算法总结来说,分为以下几种情况:(1)当left,right...
2020-03-25 12:40:35
235
原创 leetcode -[动态规划、二分查找] - (300)最长递增子序列LIS
1、问题描述给定一个无序的数组,求数组中最长递增子序列的最大长度。一个数组可能由多个递增子序列,求这些子序列中的最大长度。输入:[10,9,2,3,1,7,18]输出:4解释:最长的递增子序列为[2,3,7,18],其长度为4.2、解题思路特殊输入:数组为空的情况。解决这道问题由以下两种方法:方法1:动态规划。分析:数组numsnumsnums的最长递增子序列可能以nums[...
2020-03-25 11:14:05
553
转载 C++ - [动态内存与智能指针]
参考资料:《C++ Primer中文版 第五版》1、简介我们知道除了静态内存和栈内存外,每个程序还有一个内存池,这部分内存被称为自由空间或者堆。程序用堆来存储动态分配的对象即那些在程序运行时分配的对象,当动态对象不再使用时,我们的代码必须显式的销毁它们。在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,de...
2020-03-17 16:28:11
436
原创 leetcode -[动态规划、最大连续子数组] - 买卖股票的最佳时机(121)
1、问题描述给定一个数组,数组中的第i个元素表示一支给定股票第i天的价格。如果你最多只许完成一笔交易,即只能买入一次和卖出一次,设计一个算法来计算你能获得的最大收益。注意,你不能在买入股票前卖出股票。示例1:输入:[7,1,2,5,3,6]输出:5解释:在第2天的时候买入(股票价格为1),第6天的时候卖出(股票价格为6),可以获得最大收益6-1 = 5.示例2:输入:[7...
2020-03-13 14:35:13
237
转载 通用算法 - [特殊数据结构] - 并查集
并查集——求无向图的所有连通子图 求解无向图的连通子图,有两种方法,一种是DFS或BFS,也就是对图遍历,另一种方法就是使用并查集。对图的遍历非常常见,而并查集的概念就不如遍历那么熟悉。其实如果仅是找连通子图,用DFS对所有节点遍历一遍就可以,而用并查集则需要遍历两遍。我们不考虑算法效率问题,仅仅是通过这个问题让我们对并查集有所认识,并了解其原理,下面主要说一下并查集。 首先说一下,并查集...
2020-03-04 17:25:52
193
原创 leetcode-[自平衡二叉搜索树、桶思想] - 存在重复的元素III(220)
1、问题描述给定一个整数数组nums,k,t,判断数组中是否存在两个不同的索引i,j,使得nums[i]和nums[j]之差的绝对值不超过t,i和j之差的绝对值不超过k。2、解题思路解决这道题需要找到一组满足以下两个条件的iii和jjj:∣i−j∣≤k|i - j| \le k∣i−j∣≤k∣nums[i]−nums[j]∣≤t|nums[i] - nums[j]| \le t∣num...
2020-02-11 22:57:00
223
原创 leetcode-[数组、双指针-对撞指针] - 乘最多水的容器(11)
1、问题描述给定一个有n个非负整数的数组,以数组的索引作为x坐标,对应索引的元素值作为y坐标,找到两个坐标(x1,y1)和(x2,y2),使得他们与x轴围成的矩形面积最大。如下图所示,图中垂直线的高度代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。2、解题思路边界条件:(1)数组的元素个数小于等于2;问题分析:这道题...
2019-11-24 22:18:21
205
原创 leetcode - [链表] - (83) 删除排序链表中的重复元素
1、问题描述给定一个排序链表,删除链表中的重复元素,使得链表中的每个元素只出现一次。示例:输入:1->2->2->3->4->4->5输出:1->2->3->4->52、解题思路边界条件与特殊情况:(1)链表为空;解题思路:类比排序数组中删除重复元素的想法,如果后一个数等于前一个数,则直接该数后面所有的数往前挪一位,我们...
2019-11-24 01:17:36
93
原创 leetcode-[数组、双指针、二分搜索]-寻找重复数(287)
1、问题描述给定一个包含n+1个整数的数组nums,其中,每个整数的取值范围为[1,n],根据鸽巢原理可知,至少存在一个重复的整数。假设只有一个重复的数,找出这个数。2、解题思路边界条件与特殊情况:(1)nums中整数的个数小于2;问题分析:以nums=[1,3,4,2,3]为例,项目 | Value |-------- | -----电脑 | $1600手机 | $...
2019-11-23 21:20:45
273
原创 leetcode - [链表] - (2) 两数相加
1、问题描述使用两个非空的链表来表示两个非负整数,其中链表的每个节点存储着数位上的一个数,且按照逆序存储。将两数加和,返回一个新的链表来表示这两个数的和。您可以假设除数字0外,这两个数都不会以0开头。示例:输入:(2->4->3)+(5->6->4)输出:(7->0->8)原因:342 + 465 = 8072、解题思路边界条件:(1)两条...
2019-11-23 15:40:15
104
原创 通用算法 - [树结构] - 二叉搜索树
1. 二叉搜索树的概念二叉搜索树,又称二叉排序数或二叉查找树。它要么一棵空树,要么具有如下性质:(1)若它的左子树不为空,则左子树上所有节点的值都小于根节点的值;(2)若它的右子树不为空,则右子树上所有节点的值都大于根节点的值;(3)它的左右子树也分别为二叉排序树;下图就是一棵二叉搜索树二叉排序树具有如下优点:排序、查找、插入和删除方便;二叉排序树的中序遍历序列为所有节点的排...
2019-11-17 01:11:21
270
原创 通用算法 - [树结构] -堆
1、堆的概念堆分为两种:最大堆和最小堆,两者的差别在于节点的排序方式。在最大堆中,父节点的值比每一个子节点的值都要大。在最小堆中,父节点的值比每一个子节点的值都要小。这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立。例子:这是一个最大堆,,因为每一个父节点的值都比其子节点要大。10 比 7 和 2 都大。7 比 5 和 1都大。由于堆是存储在数组(长度为n)中的,因此,在堆...
2019-11-10 01:25:48
194
原创 通用算法 -[排序算法] - 堆排序
1、算法思想堆排序就是先将数组中元素构建成一个最大堆,然后把堆顶的元素与最后一个元素交换,交换之后破坏了堆的特性,我们再把堆中剩余的元素再次构成一个大顶堆,然后再把堆顶元素与最后第二个元素交换….如此往复下去,等到剩余的元素只有一个的时候,此时的数组就是有序的了。为方便理解我还准备了动图:2、实现代码 // 堆排序void headSort(int* arr int length) {...
2019-11-09 17:44:07
139
原创 通用算法 -[排序算法] - 基数排序
1、算法思想基数排序的排序思路是这样的:先以个位数的大小来对数据进行排序,接着以十位数的大小来多数进行排序,接着以百位数的大小……排到最后,就是一组有序的元素了。不过,他在以某位数进行排序的时候,是用“桶”来排序的。由于某位数(个位/十位….,不是一整个数)的大小范围为0-9,所以我们需要10个桶,然后把具有相同数值的数放进同一个桶里,之后再把桶里的数按照0号桶到9号桶的顺序取出来,这样一趟...
2019-11-09 17:13:55
219
原创 通用算法 -[排序算法] -冒泡排序
1、算法思想把第一个元素与第二个元素比较,如果第一个比第二个大,则交换他们的位置。接着继续比较第二个与第三个元素,如果第二个比第三个大,则交换他们的位置….我们对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样一趟比较交换下来之后,排在最右的元素就会是最大的数。除去最右的元素,我们对剩余的元素做同样的工作,如此重复下去,直到排序完成。为方便理解我还准备了动图:2、代码实现...
2019-11-09 17:01:42
140
原创 通用算法 -[排序算法] -选择排序
1、算法思想首先,找到数组中最小的那个元素,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。然后,仍然在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法我们称之为选择排序。为方便理解我还准备了动图:2、代码实现void selectSort(int* a, int length) { int...
2019-11-09 16:48:26
278
原创 通用算法 -[排序算法] -桶排序
1、算法思想桶排序就是把最大值和最小值之间的数进行瓜分,例如分成 10 个区间,10个区间对应10个桶,我们把各元素放到对应区间的桶中去,再对每个桶中的数进行排序,可以采用归并排序,也可以采用快速排序之类的。之后每个桶里面的数据就是有序的了,我们在进行合并汇总。为方便理解我还准备了图片:2、代码实现public class BucketSort { public static...
2019-11-09 16:40:38
121
原创 通用算法 -[排序算法] -计数排序
1、算法思想计数排序是一种适合于最大值和最小值的差值不是不是很大的排序。基本思想:就是把数组元素作为数组的下标,然后用一个临时数组统计该元素出现的次数,例如 temp[i] = m, 表示元素 i 一共出现了 m 次。最后再把临时数组统计的数据从小到大汇总起来,此时汇总起来是数据是有序的。为方便理解我还准备了动图:2、代码实现void countSort(int[] arr) { ...
2019-11-09 16:31:48
175
原创 通用算法 -[排序算法] -归并排序
1、算法思想归并排序的基本思想是,把大的数组划分成两个子数组,然后分别对这两个子数组分别进行排序,之后在把这两个排好序的子数组合并成一个有序的数组。由于两个小的数组都是有序的,所以在合并的时候是很快的。通过递归的方式将大的数组一直分割,直到数组的大小为 1,此时只有一个元素,那么该数组就是有序的了,之后再把两个数组大小为1的合并成一个大小为2的,再把两个大小为2的合并成4的 …… 直到全部小的...
2019-11-09 16:16:56
131
原创 通用算法 -[排序算法] -排序算法性能比较
1、算法分类0.1 算法分类十种常见排序算法可以分为两大类:非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。2、性能比较...
2019-11-09 15:48:28
318
原创 通用算法 -[排序算法] -希尔排序
1、算法由来我们知道,简单插入排序在数据规模较小和数据基本有序时十分高效。那如果数据规模较大,并且无序时,有什么样的方法可以提高简单插入排序的效率呢?2、算法思想3、代码实现4、算法分析...
2019-11-09 15:33:08
201
原创 通用算法 -[排序算法] - 快速排序
1、算法思想快排算法的基本思想是,选取待排序数组中的任意一个元素作为基准值,遍历数组中的元素。把小于基准值的元素放到基准值的左边,大于基准值的元素放到基准值的右边,基准值放到两者之间,此时,基准值到达最终的位置。然后对基准值左边的子数组和右边的子数组采用同样的方式处理,直到子数组区间为1缩小为1,说明数组有序。快排的递归实现:template<typename T>void q...
2019-11-09 00:42:25
281
原创 C++模块-[随机数] -rand()函数
1、随机数产生原理C++通过rand()和函数产生随机数,rand()的内部是用线性同余法实现的,所以生成的并不是真正的随机数,而是在一定范围内可看为随机的伪随机数。2、rand()函数rand()会返回一随机数值, 范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h, 其值为2147483647。#include <iostream>#include &...
2019-11-08 23:10:33
438
原创 leetcode - [链表、排序] - (148)排序链表
1、问题描述在O(nlogn)O(nlogn)O(nlogn)的时间复杂度和O(1)O(1)O(1)的空间复杂度内对链表进行排序。例如:输入: 3->2->1->5->4输出:1->2->3->4->52、解题思路思路1:最简单的方法是利用选择排序的思想,每次从链表中选择第k大的数,插入表头(头节点的后面),k=1,2,…,n。这种方法...
2019-11-02 23:59:53
196
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人