自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(48)
  • 收藏
  • 关注

原创 剑指Offer46.把数字翻译成字符串

题目:给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。示例:输入:12258输出:512258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”思路:我们可以把这道题当成有条件的跳台阶来做,本质还是动态规划我们可以定义一个动态数组dp[],每一个dp[i]表

2021-10-15 17:11:00 200

原创 SpringBoot自定义starter启动器

根据项目需求自定义一个启动器starter

2021-08-15 20:21:09 382

原创 SpringBoot自动装配原理解析(分析源码)

从源码角度分析并理解SpringBoot的自动装配过程

2021-08-12 20:48:47 302

原创 LeetCode 139.单词拆分

题目:给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。思路:这道题我们使用动态规划来做首先定义一个dp数组,dp[i]就表示当前位置之前的字符串[0,i - 1]是否满足题目所给条件,即能否被拆分成目标所给的单词,而要满足该条件,我们只需要找到最后一个单词是否合法以及除去该单词的前面区间是否合法因此,我们可以设置一个分割点j,如果[0,j

2021-07-27 16:39:03 175

原创 LeetCode 136.只出现一次的数字

题目:给定一个非空整数数组nums,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗样例输入:[4,1,2,1,2]输出:4思路:这道题有一种非常巧妙的做法,运用到了位运算的知识。首先我们要了解位运算中异或运算的相关性质:假设有一个数a,则有:a ^ 0 = a,a ^ a = 0,并且异或运算满足交换律因此我们可以将整个数组遍历一遍,出现两次的数进行异或运算之后就会抵消变成0,最后剩下

2021-07-26 13:13:54 105

原创 LeetCode 128.最长连续序列

最长连续序列

2021-07-24 13:39:58 77

原创 LeetCode 121.买卖股票的最佳时机

题目:给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回0。思路:本题最容易想到的就是暴力解法,两次循环遍历数组,求最大值。此方法时间复杂度为O(n²),我们需要将他进行改进我们可以在遍历的时候定义一个当前历史最小值minPrice,试想一下生活中我们肯定希望

2021-07-23 13:38:43 132

原创 LeetCode 84.柱状图中最大的矩形

题目:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。思路:首先可以想到暴力法,遍历一遍高度数组heights[],每次遍历一个矩形位置,就对他的左右两边界进行判断,如果左边或右边高度大于等于当前位置,就也可以包括进来,求出面积并和最大面积做对比进行更新。暴力法的时间复杂度为O(n²),我们可以通过空间换时间的角度来降低时间复杂度为O(n)我们可以设置一个栈空间来保存每一个位置的索引,因为高度可以通过数组得出

2021-07-10 18:17:19 93

原创 LeetCode 79.单词搜索

题目:给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用思路:该题目是一道典型的深度优先搜索DFS+回溯算法题首先我们可以设置一个visited[][]数组用来存储当前字符是否遍历过,防止重复遍历。设置一个curindex用来表示当前遍历到了哪一个字符串。

2021-07-09 20:30:31 106

原创 LeetCode 78.子集

题目:给你一个整数数组 nums ,数组中的元素互不相同 。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。思路:该题目是回溯类型的一种,相同类型的题目还有全排列等等。但是这道题还是和全排列有些不同的因为求子集,我们从第一个元素出发,所有情况都要加入到res集合中,没有临界条件,等curindex超过数组长度nums.length时,就自动退出方法因为每种情况都是在上一个元素选择或不选择的基础上来的,所以dfs方法中的循环每次都需要从curindex开始,一

2021-07-06 18:06:48 97

原创 LeetCode 76.最小覆盖子串

题目:给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。思路:...

2021-07-05 19:22:03 204

原创 LeetCode 75.颜色分类(荷兰国旗问题)

题目:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、1 和 2 分别表示红色、白色和蓝色思路:本题是典型的荷兰国旗问题,我们不能仅仅局限于当前题目,有的题目变一下就不是三个数,而是三个区域,小于num的,等于num的以及大于num的。为了规划区域,我们可以设置两个指针left,right,left表示左边区域的右边界,初始时指向第一个元素的前一个,索引为-1,right表示右边区域的左边

2021-07-04 13:49:37 334

原创 LeetCode 72.编辑距离

题目:给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符思路:本题目可以使用动态规划来做,首先创建二维数组dp[i][j],表示当前情况word1的前i个字符和word2的前j个字符的编辑距离。首先应该分情况讨论当两个字符串的最后一位都相同时,dp[i][j] = dp[i - 1][j - 1];当最后一位不相同时,那么最后一位就需要通过替换一步来保证相

2021-07-03 17:14:27 88

原创 LeetCode 64.最小路径和

题目:给定一个包含非负整数的 m x n 网格 grid ,网格上的每个位置都有一个数字,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。思路:本题目可以用动态规划来做,首先创建一个二维动态数组dp[i][j]来表示每一个位置的路径,因为每个一位置的路径和只能由它左边或者上边的数字值决定,并且因为求的是最小路径,所以可以得出动态转移方程dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j -

2021-07-02 17:23:48 142

原创 LeetCode 62.不同路径

题目:一个机器人位于一个 m x n 网格的左上角机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下。问总共有多少条不同的路径?思路:该题目我首先想到的是深度优先搜索DFS,结果超时了,有的边缘案例没有过,后来发现可以用动态规划来做我们可以定义一个二维dp数组由于机器人只能向右或者向下走,因此当前位置可以由前一个位置向右走一步或者向下走一步到达,可以得到动态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]由于机器人只能向右或者下走,因此第一行的

2021-07-01 11:55:31 89

原创 LeetCode 56.合并区间

题目:以数组intervals表示若干个区间的集合,其中单个区间为intervals[i] = [starti, endi]。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间思路:本题目需要先按照区间的起始索引starti对应的值进行递增排序这样的话当前区间和下一个区间无非就两种大情况待比较区间的开始值大于当前区间的结束值,那么肯定没有重合区间,直接将其加入待比较区间的开始值小于等于当前区间的结束值,那么就存在重合区间了,这时就需要通过比较更新当前区间的

2021-06-30 15:59:50 141

原创 LeetCode 55.跳跃游戏

public boolean canJump(int[] nums) { int len = nums.length; // 维护一个变量保存最远可以到达的位置,初始为0 int maxLength = 0; for(int i = 0; i < len; i++){ // 首先判断该位置是否可达,也就是索引是否小于等于最远位置 if(i <= maxLength){ ...

2021-06-29 19:28:59 99

原创 LeetCode 53.最大子序和

题目:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。思路:动态规划这道题很明显可以使用动态规划来做,可以设置一个数组dp[],每个位置的值保存的是当前情况下的最大值设置一个变量res存储最终结果,每次遍历一个数,如果dp[i-1]>0,那么就将当前位置的dp[i] = dp[i - 1] + nums[i],否则dp[i] = nums[i],每次比较之后更新res'的值,最后返回结果即可以下为代码+注释: public i

2021-06-25 13:15:54 87

原创 LeetCode 49.字母异位词分组

题目:给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串思路:我们可以开辟一个哈希表map空间,由于两个异位词按照字典序排序之后一定是相同的,因此我们可以用键key存放字符串按照字典序升序排好之后的String类型的值,而值value存放一个list集合,集合中存放的是当前key的所有异位词字符串遍历字符串数组的时候,首先判断该字符串按照字典序排序之后的值在map中有没有对应的值list集合,没有就创建一个,遍历结束不要忘记把当前字符串s存入list集合中以下

2021-06-23 13:09:07 136

原创 LeetCode 48.旋转图像

题目:给定一个 n × n 的二维矩阵matrix表示一个图像。请你将图像顺时针旋转 90 度。进阶:在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。思路:笔者粗略画了一个4X4的例子图,可以把每种颜色的数字当作一个小整体,他们各自都按照顺时针箭头的方向旋转。以蓝色部分的数字2作为基准,假设数字2所在的位置为matrix[row][col],那么旋转90度之后就到了绿色部分位置8,该数字的行号是基准数字2的列号,列号是矩阵长度-基准数字2的差,因此8的索引位置

2021-06-22 18:56:15 154

原创 LeetCode 46.全排列

题目:给定一个不含重复数字的数组nums ,返回其所有可能的全排列 。你可以按任意顺序返回答案。思路:方法:深度优先搜索(DFS)+回溯可以设置一个状态变量数组used[],默认值为0时,表示该索引对应的值没有被遍历过,如果为1,表示已经遍历过,这样只用O(1)的时间复杂度就能找到该数是否可用,典型的拿空间换时间因为是数组的全排列,因此我们每次遍历一个数时,就在当前状态的基础上对数组进行遍历,设置一个集合res来存储所有的可选情况,动态集合cur来存储当前的情况设置一个变量index表示当前遍

2021-06-21 19:38:38 56

原创 LeetCode 42.接雨水

题目:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。思路:本题有多种解法,本文将介绍两种按列求每一列雨水量的做法使用动态规划,具体做法为设置两个数组leftMax[],rightMax[]用来保存每一列左边的最高墙高度和右边的最高墙高度。依次遍历每一列,在每一列中,求出当前列左边最高墙高度和右边最高墙高度较矮的那一个,根据木桶效应,当前列能否接到雨水就取决于较矮墙的高度,维护一个变量sum来保存总雨水量,将每一列都遍历一遍,就可以得到可以接到的

2021-06-17 13:17:56 95

原创 LeetCode 39.组合总和

题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。思路:本题是一道典型的DFS深度优先搜索+回溯+剪枝。首先设置一个List类型的集合res存放总结果,再设置一个cur存放当前情况下的结果因为剪枝的前提是数组有序,因此先将数组排序,然后通过DFS递归遍历数组,如果总和超过target,由于数组是升序遍历,后面的数肯定都不满足了,直接bre

2021-06-15 13:06:13 164 2

原创 LeetCode 34.在排序数组中查找元素的第一个和最后一个位置

题目:给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。思路:首先能想到的就是一遍for循环解决,但这样做时间复杂度为O(n),并且没有使用到题目中所给的数组是升序排列的条件为了使时间复杂度降到O(logn),我们可以使用二分查找首先 ,查找第一个位置start和最后一个位置end,第一个位置start我们可以通过找到第一个大于等于target的值来实现,第二个位置

2021-06-14 15:14:24 119

原创 LeetCode 33.搜索旋转排序数组

题目:整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。给你 旋转后 的数组 nums 和一个整

2021-06-13 14:01:57 67

原创 LeetCode 32.最长有效括号

题目:给你一个只包含 ( 和 ) 的字符串,找出最长有效(格式正确且连续)括号子串的长度注意:该最长有效括号一定要是连续的!思路:本题可以使用动态规划解决,首先创建一个数组dp[],用来保存当前位置的最长有效子串数量首先明确有效子串的条件,当前位置的字符一定为),并且前面存在字符((Tips:不一定是紧挨着当前这个)的),如果当前位置的字符为(,那么该位置的dp值一定为0。因此分两种小情况,在当前位置i字符为)时:如果前一个字符s.charAt(i - 1)为(,那么当前位置上dp[i]=

2021-06-11 14:27:13 497 2

原创 LeetCode 31.下一个排列

题目:实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列。必须原地修改,只允许使用额外常数空间样例输入:nums = [1,2,3]样例输出:[1,3,2]思路:我们需要找到一个靠左的小数和一个靠右的大数,然后让二者交换,再将交换之后大数后面的元素升序排序,保证是下一个更大的排列因为是紧邻着的下一个更大排列,因此我们要从数组尾部遍历找到第一个相邻的升序对使得nums[i]<nums[

2021-06-10 14:04:11 72

原创 LeetCode 22.括号生成

题目:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。样例输入:3样例输出:["((()))","(()())","(())()","()(())","()()()"]思路:该题目需要将全部的情况都遍历,然后取出符合情况的情况可以使用回溯+深度优先遍历DFS或者广度优先遍历BFS,本题解采用深度优先遍历给定一个数字n,设置两个变量left,right分别存放左括号和右括号的剩余数量,遍历过程中只有一个剪枝情况:当剩余的左括号数量比右括号数量大时,相当

2021-06-09 12:59:14 124

原创 LeetCode 17.电话号码的字母组合

题目:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。(每个数字代表的字符就是平常九宫格中所代表的字符,如:2代表abc,3代表def。。。以此类推)样例输入:“23”样例输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]思路:字符串中的每个数字都能延伸出不同的几种情况,在每一个情况的基础之上的下一个字母又能延伸出多种情况因此我们可以使用回溯来做本题,首先开辟一个map数组来存放每个数字所代表的字符,之

2021-06-08 20:43:39 92

原创 LeetCode 15.三数之和

题目:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组思路:最基本的做法就是三重for循环暴力解法,但是这样时间复杂度为O(n^3),太慢了我们可以使用排序+双指针的方式降低时间复杂度首先我们先将数组按照从小到大的顺序排序第一重循环还是遍历第一个元素i,并设置一个target=-nums[i],也就是后两个元素的和应该等于target才能保证三数之和为0第二重循环遍历第二

2021-06-06 13:26:21 68

原创 LeetCode 11.盛水最多的容器

题目:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。简单来说就是给定一个数组,索引代表位置(从0到n…),值代表该位置的高度,求该数组中两个位置之间所能盛水的最大面积。既然是盛水最多,那么肯定和两个边中高度较低那个相关联。面积也就等于:两位置之间的距离*较小边的高度。返回这个数组中所有面积中最大的那个。

2021-06-05 13:01:39 121

原创 LeetCode 3.无重复字符的最长子串

题目:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度思路:最暴力的方法当然是两层for循环遍历完所有情况,找出以当前字符为开头的每个无重复子串,然后比较得出最大的那个但是,我们可以采用滑动窗口的方法做出优化。具体做法:维护两个指针start和end,一个指向当前无重复子串的开头位置,一个指向结束位置每次循环前先确定start开头索引,之后对字符串中的元素进行遍历不断更新end指针的位置,直到碰到第一个重复的字符则结束如何判断当前字符串中没有重复元素?我们可以维护一

2021-06-04 14:07:46 83

原创 LeetCode 4.寻找两个正序数组的中位数

题目:给定两个正序数组(数值从小到大排列)nums1和nums2,求出并返回两个数组的中位数思路:总的来说分两种思路:第一种简单易想,就是将两个数组按照正序合并成一个新的数组,之后根据索引返回它的中位数。时间复杂度为O(m+n),也就是遍历两个数组的时间。空间复杂度为O(m+n):开辟了一个新的数组以下为第一种方法代码+注释:比较简单,本文主要说明第二种方法一:暴力解法:时间复杂度O(m+n) public double findMedianSortedArrays(int[] nums1

2021-06-03 17:03:02 139

原创 LeetCode 10.正则表达式匹配

题目:给定一个字符串s和一个字符规律字符串p,请实现一个支持*和.的字符串匹配,判断该字符规律p能否匹配上字符串s。其中:.可以匹配单个字符*可以匹配任意个前面的字符思路:本题需要采用动态规划来做,求出部分解,之后通过部分解得出更大范围的解。根据提供的信息我们可以知道,"*"前面一定是有字符的,并且每个.*都能匹配任意两个字符。大体总共分两种情况:当前匹配串中最后的字符不为*。那么要么匹配s串中的字符,要么不匹配,没有其他情况:如果匹配上了,那么:dp[i][j] = dp[i -

2021-06-02 13:19:46 118

原创 LeetCode 101.对称二叉树

题目:给定一个二叉树,查看其是否为镜像对称。思路:该题意思就是左子树和右子树相对位置的值是否相同(都为空也算相同)可以每次让当前节点的左子树和右子树比较。初始两个节点都指向根节点,之后一个指向左子树,一个指向右子树相比,然后交换一个指向右子树,一个指向左子树相比。反复递归如果都为true,那么最终结果就为true,如果其中有一个不相同就返回false以下为代码+注释,代码结合注释会好理解一点:public boolean isSymmetric(TreeNode root) {

2021-05-31 19:38:20 73

原创 LeetCode 617.合并二叉树

题目:给定两个二叉树,返回二者合并之后的结果合并规则:如果两个二叉树相同位置上都有节点,那么将他们的值相加作为该节点处的新值,否则不为null的节点直接作为当前节点的值思路:本题比较简单,利用深度优先遍历DFS,将每一个节点位置都遍历一遍,更新该位置的值即可以下为代码+注释: //定义TreeNode节点 class TreeNode{ int val; TreeNode left; TreeNode right; TreeNode(int val){ this.val

2021-05-29 12:27:05 137

原创 LeetCode 662.二叉树最大宽度

题目:给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空定义宽度为:每一层最左边非空节点和最右边非空节点之间的距离思路最容易想到的就是宽度优先遍历(BFS) 或者 深度优先遍历(DFS)本文以宽度优先遍历进行阐述。...

2021-05-28 13:19:37 162

原创 LeetCode 543.二叉树的直径

题目:求出一个二叉树的最大直径直径定义:二叉树中任意两个节点之间的距离,也就是两点之间共有多少条边连通。思路:因为每一个节点都只有左子树和右子树两条路径可以走,每走一个点,路径值也就加一。所以该题目可以转化为求当前节点的左子树节点和右子树节点之和的最大值。可以通过深度优先遍历每次遍历一个节点,就求出当前情况下的最大值,将整个二叉树的节点遍历完,最大值也就求出来了。该题和LeetCode 124.二叉树中的最大路径和很相似,都利用了分治思想,先递归求子问题的解,再根据子问题的解求出更大的问题的解

2021-05-27 13:08:19 114

原创 LeetCode 538.把二叉搜索树转换为累加树

题目:将一个二叉搜索树的每个节点值都重新赋值为:这棵树中所有大于等于当前节点值的所有值之和。首先我们要明白二叉搜索树的定义:每个节点node如果有左子树,那么左子树的所有节点值一定都小于当前节点值node.val每个节点node如果有右子树,那么右子树的所有节点值一定都大于当前节点值node.val结合中序遍历的特点:左子树,根节点,右子树。那么中序遍历整个二叉搜索树,得到的就会是一个递增序列,而每一个节点所更新的值其实就是递增序列中当前值后面的所有值之和,因此,我们现在要做的就是求这些值

2021-05-26 13:00:38 93

原创 LeetCode 208.实现Trie(前缀树)

LeetCode 208.实现Trie(前缀树)首先,我们要了解前缀树的概念。通常来讲前缀树是用来存储字符串的一种树形结构,每个节点都代表字符。并且,前缀树有一个特性,每一个节点的子节点都和该节点有相同的前缀,不然也不可能成为它的子节点,这也是前缀树名字的由来。前缀树主要包含插入insert,删除delete,查找字符串search,查找前缀prefixNum这四种操作,以下为实现前缀树的代码:class Trie{ class TrieNode{ //表示每个节点被经过了多

2021-05-25 20:34:50 95

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除