![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
【Java】 数据结构与算法
记录整理自己学习数据结构与算法的历程
念奕玥
这个作者很懒,什么都没留下…
展开
-
【搜索】2、岛屿的数量(medium)
leetcode 200 岛屿的数量同是岛屿问题,同样是用网格来表示。可以复用岛屿周长的思路:基本的dfs框架;搜索遍历的停止方式。class Solution { public int numIslands(char[][] grid) { //记录岛屿数量。 int count=0; //对整个网格进行遍历 for(int i=0;i<grid.length;i++){ for(int j=0;j<原创 2021-07-19 20:10:22 · 218 阅读 · 0 评论 -
【搜索】(DFS)1、岛屿的周长(easy)
深度优先搜索DFS和广度优先搜索BFS是两种最常见的优先搜索方法,被广泛地运用在图和树等 结构中进行搜索。深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进。深度优先搜索也可以用来检测环路:记录每个遍历过的节点的父节点,若一个节点被再次遍历且父节点不同,则说明有环。我们也可以用之后会讲到的拓扑排序判断是否有环.原创 2021-07-19 19:53:20 · 158 阅读 · 0 评论 -
【二分查找】4、寻找旋转排序数组中的最小值 II(hard)
leetcode 154寻找旋转排序数组中的最小值 II原创 2021-07-06 16:50:54 · 157 阅读 · 0 评论 -
【二分查找】3、搜索旋转排序数组Ⅱ(medium)
leetcode 搜索旋转排序数组Ⅱclass Solution { public boolean search(int[] nums, int target) { if(nums.length==0||nums==null) return false; int left=0,right=nums.length-1; while(left<=right){ int mid= left+(right-left)/2;原创 2021-07-05 13:27:27 · 101 阅读 · 0 评论 -
【二分查找】2、在排序数组中查找元素的第一个和最后一个位置(medium)
leetcode 34 在排序数组中查找元素的第一个和最后一个位置原创 2021-07-04 21:54:38 · 272 阅读 · 0 评论 -
【二分查找】1、x的平方根(easy)
二分查找也常被称为二分法或者折半查找,每次查找时通过将待查找区间分成两部分并只取一部分继续查找,将查找的复杂度大大减少。对于一个长度为 O(n) 的数组,二分查找的时间复杂度为 O(log n)。举例来说,给定一个排好序的数组 {3,4,5,6,7},我们希望查找 4 在不在这个数组内。第一次折半时考虑中位数 5,因为 5 大于 4, 所以如果 4 存在于这个数组,那么其必定存在于 5 左边这一半。于是我们的查找区间变成了 {3,4,5}。(注意,这里的 5 可以保留也可以不保留,并不影响时间复杂度.原创 2021-06-30 23:25:48 · 121 阅读 · 1 评论 -
【双指针】最小覆盖子串(滑动窗口)(medium)
若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。leetcode 76最小覆盖子串思路:使用滑动窗口求解,即两个指针 l 和 r 都是从最左端向最右端移动,且 l 的位置一定在r 的左边或重合。...原创 2021-06-30 13:19:59 · 150 阅读 · 2 评论 -
【双指针】3、环形链表Ⅱ(快慢指针)
对于链表找环路的问题,有一个通用的解法——快慢指针(Floyd 判圈法)。给定两个指针,分别为 slow 和 fast,起始位置均在链表的开头。每次 fast 前进两步,slow 前进一步。如果 fast可以走到尽头,那么说明没有环路;如果 fast 可以无限走下去,那么说明一定有环路,且一定存在一个时刻 slow 和 fast 相遇。当 slow 和 fast 第一次相遇时,我们将 fast 重新移动到链表开头,并让 slow 和 fast 每次都前进一步。当 slow 和 fast 第二次相遇时,.原创 2021-06-24 20:23:24 · 158 阅读 · 2 评论 -
【双指针】2、合并两个有序数组
leetcode 88. 合并两个有序数组分析:两个数组都有序。把nums2合并到nums1中去,不额外新建数组。思路:两个数组,所以一个数组放一个指针。由于数组都有序,所以指针的开始位置可以选择都从头或尾开始。由于需要把nums2合并到nums1中去,指针从头部开始遍历容易造成nums1原本数据被覆盖掉,所以选择两个指针都从数组的尾部开始。然后开始对两个数组的值进行比较。class Solution { public void merge(int[] nums1, int m, int原创 2021-06-23 12:01:44 · 1085 阅读 · 0 评论 -
【双指针】1、两数之和(easy)
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。leetcode 167. 两数之和 II - 输入有序数组分析:给定数组已排好序,寻找和为target的两个数字。思路:两个指针i,ji,ji,j分别指向数组的头和尾,移动方向相反。.原创 2021-06-23 11:00:02 · 274 阅读 · 0 评论 -
【贪心算法】4、用最少数量的箭引爆气球
leetcode 452 用最少数量的箭引爆气球此题与 455 分发饼干异曲同工。解决思路:贪心策略:从第一个气球开始找,只要能有1支箭的就不多用,1支箭完成不了的再用下一支箭。把所有气球的范围在同一条横轴上画出来更易理解。判断能不能用同一支箭(气球有没有重叠):气球i+1i+1i+1的左边界小于等于气球iii的右边界过程:首先对气球按右边界的大小进行升序排序。然后选标准(与哪一个气球进行比较算是相重叠),右边界设置为标准的右边界。先以第一个气球为标准,与第一个气球有重叠的气球,可共用一支原创 2021-06-22 13:03:25 · 173 阅读 · 0 评论 -
【贪心算法】3、种花问题(easy)
看题目就很容易想到利用贪心来解题。为了在现有地块中种上更多的花,所以贪心策略为只要有符合种花条件的地块,就在该地块上种花。所以遍历所有地块,看最多能种的花是否大于等于要种的花。判断地块iii是否能种花需要判断三处:当前地块iii,地块i−1i-1i−1,地块i+1i+1i+1,一般情况下,这三块地块的值需均为0(未种花状态)flowerbed[i]==0 && flowerbed[i-1]==0 && flowerbed[i+1]==0 特殊情况:i==0.原创 2021-06-21 18:15:33 · 310 阅读 · 0 评论 -
【贪心算法】2、无重叠区间(中等)
leetcode 435、无重叠区间利用贪心算法的解题思路:class Solution { public int eraseOverlapIntervals(int[][] intervals) { int n = intervals.length; if(n==0) return 0; Arrays.sort(intervals,new Comparator<int[]>(){ @Override原创 2021-06-21 14:52:14 · 159 阅读 · 0 评论 -
【贪心算法】1、分发饼干
贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。可用于解决分配问题e.g.leetcode 455 分发饼干解题思路:目标:尽可能满足越多数量的孩子。根据目标,可以容易想到,先去满足胃口值小的孩子。为了尽量使饼干可以满足更多的孩子,所以要把饼干尺寸大于等于孩子胃口值的饼干中挑尺寸最小的饼干给孩子。满足了这个孩子之后,再采取同样的策略去考虑剩下的孩子,直到孩子全被满足或者没有符合条件的饼干。对孩子胃口值和饼干尺寸进行排序,便于从胃口值最小.原创 2021-06-21 10:55:26 · 657 阅读 · 0 评论 -
排序算法对比
平方阶O(n2)O(n^2)O(n2)排序:直接插入、直接选择和冒泡排序线性对数阶O(nlog2n)O(nlog_2n)O(nlog2n)排序:快速排序、堆排序和归并排序O(n(1+δ))O(n^{(1+\delta)})O(n(1+δ))排序,δ\deltaδ是介于0和1之间的常数:希尔排序线性阶O(n)O(n)O(n)排序:基数排序,桶、箱排序论是否有序的影响:当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O(n)O(n)O(n);而快速.原创 2021-06-01 11:11:10 · 98 阅读 · 0 评论 -
排序之直接插入排序(java)
具体步骤如下:默认第一个元素已经被排序,获取下一个元素在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于新元素,将该元素移到下一位置,直到找到已排序的元素小于或者等于新元素的位置,将新元素插入到该位置重复步骤2-3public class selectsort { public static void main(String[] args) { int[] arr = {13,5,2,8,32,56,32,421,78,4}; sort(arr原创 2021-05-31 19:28:17 · 86 阅读 · 0 评论 -
排序之堆排序(Java)
堆排序是利用堆这种数据结构所设计的一种排序算法。堆实际上是一个完全二叉树结构。 完全二叉树:假设一个二叉树的深度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边。堆又分两种:大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;堆排序的核心步骤:将待排序的数组初始化为大顶堆,该过程即建堆。将堆顶元素与最后一个元素进行交换,除去最后一个.原创 2021-05-31 19:04:24 · 76 阅读 · 0 评论 -
排序之快速排序(java)
快速排序是由东尼·霍尔所发展的一种排序算法。 在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。 事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner> loop)可以在大部分的架构上很有效率地被实现出来。基本思想分治法。快速排序又是一种分而治之思想在排序算法上的典型应用。使用分治法(Divide and conquer)把一个串行(list)分为两个子串行(sub-lists)。本质.原创 2021-05-31 16:36:31 · 131 阅读 · 0 评论 -
求解最短路径
迪杰斯特拉(Dijkstra)算法——计算一个节点到其他所有节点的最短路径弗洛伊德算法(Floyd)——求每一对顶点之间的最短路径参考原创 2021-04-13 15:22:23 · 55 阅读 · 0 评论 -
牛客 跳台阶问题编译错误
在牛客上做题时出现了以下错误:对应的代码是:public class Solution { public int JumpFloor(int target) { if(target<=2) return target; int a=1,b=2; int res=0; for(int i=3;i<=target;i++){ res=a+b; a=b;原创 2021-04-06 14:29:14 · 312 阅读 · 0 评论 -
动态规划的直观理解
动态规划的理解漫画直达!!!以斐波那契数列举例,简单易懂动态规划三个重要概念:边界最优子结构状态转移公式原创 2021-03-30 09:51:01 · 88 阅读 · 0 评论 -
排序之冒泡排序的实现
排序之冒泡排序的实现通过对数组中的元素进行两两比较的方法来实现冒泡图1.1 冒泡之两两比较的图解(注,图片中内容来源于尚硅谷数据结构课程笔记,侵删对第1种进行优化从图1.1中可以看到,在第二趟排序中就已经完成了对数组的排序,不需要再进行第3,4趟,这也是进行优化的地方。数组中的每一个元素值依次与后面的元素值进行一一比较...原创 2021-03-10 23:49:42 · 411 阅读 · 0 评论