leetcode题目(1)
🎈202. 快乐数
难度简单1063
编写一个算法来判断一个数 n 是不是快乐数。
[快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
这题目上来就一脸懵逼, 暴力计算肯定就又TLE了, 既然是个简单题, 那应该是有什么小窍门
快乐的知识点增加了 - 快乐数 - 力扣(LeetCode)
链表找环
每个数字都会根据 各位平方和 指向另一个数字,所以从任意数字开始进行 各位平方和 的迭代操作,就相当于在链表上游走。如果 无限循环 但始终变不到 1,那说明肯定是链表游走到了环。
为什么呢? (此处应该有图)
为什么无限循环就一定是走到了环了呢?而不是链表上的数字越变越大?这里我来给一个证明。
通过上面的证明, 本题也就化为了链表找环问题 ,
快慢指针
slow每次走一步, fast每次走两步,
这里的走步 , 其实就求平方和 ,
当slow==fast的时候, 相当于进入环了,
fast超slow整整一个环
返回结果就是slow是否为1
其实本题最后如果slow==fast==1 , 1 本身就是一个环
代码如下
123456789101112131415161718class Solution { public boolean isHappy(int n) { int slow=n,fast=squareSum(n); while(slow!=fast){ slow=squareSum(slow); fast=squareSum(squareSum(fast)); } return slow==1; } int squareSum(int n){ //求平方和 int sum=0; while(n!=0){ sum+=(n%10)*(n%10); n/=10; } return sum; ...
07springboot指标监控
8、指标监控
1.SpringBoot Actuator与Endpoint
未来每一个微服务在云上部署以后,我们都需要对其进行监控、追踪、审计、控制等。SpringBoot就抽取了Actuator场景,使得我们每个微服务快速引用即可获得生产级别的应用监控、审计等功能。
官方文档 - Spring Boot Actuator: Production-ready Features
1.x与2.x的不同:
SpringBoot Actuator 1.x
支持SpringMVC
基于继承方式进行扩展
层级Metrics配置
自定义Metrics收集
默认较少的安全策略
SpringBoot Actuator 2.x
支持SpringMVC、JAX-RS以及Webflux
注解驱动进行扩展
层级&名称空间Metrics
底层使用MicroMeter,强大、便捷默认丰富的安全策略
如何使用
添加依赖:
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>
访问http://localhost:8080/actuator/**。
暴露所有监控信息为HTTP。
123456management: endpoints: enabled-by-default: true #暴露所有端点信息 web: exposure: include: '*' #以web方式暴露
测试例子
http://localhost:8080/actuator/beans
http://localhost:8080/actuator/configprops
http://localhost:8080/actuator/metrics
http://localhost:8080/actuator/metrics/jvm.gc.pause
http://localhost:8080/actuator/metrics/endpointName/detail ...
算法基础day 19~20 others
👉day 19位运算
201. 数字范围按位与
难度中等398
给你两个整数 left 和 right ,表示区间 [left, right] ,返回此区间内所有数字 按位与 的结果(包含 left 、right 端点)。
0 与谁与都为 0 ,因此只要有一个0,那么无论有多少个 1都是 0
本题其实就是需要求这两个数字的二进制表示的公共前缀,
以5 , 7 为例
可以看到,5 和 7 二进制形式存在公共前缀 01 ,因此从 5 → 7 ,其前两位 01 是一直不变的,只有后两位一直在变化,从 01 → 11。
我们可以确定按位与的结果,前两位一定是 01。
根据公共前缀确定结果前两位为 01,接下来就要确定剩余部分按位与结果。
若存在剩余部分,剩余部分的表现形式一定是 0XXX → 1XXX。举个极端的例子 01111111 → 10000000(相差仅为 1 )。
即使在最极端的情况下,剩余部分中每一位也一定存在 0 ,因此我们可以认定,剩余部分按位与结果一定为 0。
👉day 20其他
384. 打乱数组
labuladong 题解
难度中等296
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果
【宫水三叶】洗牌算法模板题 - 打乱数组 - 力扣(LeetCode)
洗牌算法
123456789101112131415161718192021222324class Solution { int[] nums; int n; Random random = new Random(); public Solution(int[] _nums) { nums = _nums; n = nums.length; } public int[] reset() { return nums; } public int[] shuffle() { int[] ...
背包问题
1️⃣ 01背包问题
有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
首先可以回溯搜索出所有的情况 , 但是这样一来时间复杂度直接起飞 O(2n) , 需要使用动态规划来进行优化
背包最大重量为4。
物品为:
重量
价值
物品0
1
15
物品1
3
20
物品2
4
30
问背包能背的物品最大价值是多少?
二维dp数组01背包
1.确定dp数组以及下标的含义
对于背包问题,有一种写法, 是使用二维数组,即**dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少**。
二维数组的定义,可以看下面这个图:
要时刻记着这个dp数组的含义,下面的一些步骤都围绕这dp数组的含义进行的,如果哪里看懵了,就来回顾一下i代表什么,j又代表什么。
2.确定递推公式
再回顾一下dp[i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
那么可以有两个方向推出来dp[i][j],
不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。
其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。
放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值
所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
3.dp数组如何初始化
关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱。
首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。如图:
在看其他情况。
状态转移方程dp ...
算法基础day 16~18 DP
👉day 16
300. 最长递增子序列
labuladong 题解思路
难度中等2745
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
注意子序列以及子串, 对于子序列, 只需要保证顺序就行, 而子串需要保证连续
dp数组含义, : dp[i] 代表以nums[i] 结尾时, 数组的最长递增子序列
状态转移: 我们从当前的数组往前遍历 , 当遇到了比当前的num[i] 小的数时, 那么dp[i]=Math.max(dp[i],dp[j]+1)
dp数组初始化 : 由于每一个子序列至少含有一个元素, 因此dp数组的所有元素都应该初始化为 1
遍历方向以及范围: 从左向右顺序遍历 , 范围就是dp数组的所有数字
返回值 : 在遍历的过程中, 维护res , 每次都取最大值, 最后返回 , 记为最长递增子序列
123456789101112131415161718class Solution { public int lengthOfLIS(int[] nums) { if(nums.length==1) return 1; int res=0; int[]dp=new int[nums.length]; //dp[i]表示 以nums[i]结尾的最长的递增的子序列的长度 Arrays.fill(dp,1); // 初始化为 1 for (int i = 0; i < nums.length; i++) { for (int j = i-1 ; j >= 0; j--) { if(nums[i]>nums[j]){ // 注意不能执行完了一次if就直接跳出循环了, 因为元素的顺序与子序列的长度没关系 dp[i]=Math.max(dp[i],dp[j]+1); } } res=Math.max(re ...
06springboot 数据访问&单元测试.md
六、数据访问
1.数据库场景的自动配置分析与整合测试
1️⃣导入JDBC场景
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId></dependency>
接着导入数据库驱动包(MySQL为例)。
数据库驱动?
为什么导入JDBC场景,官方不导入驱动?官方不知道我们接下要操作什么数据库。
数据库版本和驱动版本对应
123456789101112131415161718<!--默认版本:--><mysql.version>8.0.22</mysql.version><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!--<version>5.1.49</version>--></dependency><!--想要修改版本1、直接依赖引入具体版本(maven的就近依赖原则)2、重新声明版本(maven的属性的就近优先原则)--><properties> <java.version>1.8</java.version> <mysql.version>5.1.49</mysql.version></properties>
注意数据库的版本和驱动的版本对应
高版本的可以向下兼容
2️⃣相关数据源配置类
1.自动配置的类
DataSourceAutoConfiguration : 数据源的自动配置。
修改数据源相关的配置:spring.datasource。
数据库连接池的配置,是自己容器中没有DataSource才自动配置的。
底层配置好的连接池是:HikariDataSource。
DataSourceTransaction ...
05springboot web开发(3)
7、文件上传
1.单文件与多文件上传的使用
页面代码
1/static/form/form_layouts.html
多文件上传, 使用multiple
12345678910111213141516171819202122232425262728<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data"> <div class="form-group"> <label for="exampleInputEmail1">邮箱</label> <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"> </div> <div class="form-group"> <label for="exampleInputPassword1">名字</label> <input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password"> </div> <div class="form-group"> <label for="exampleInputFile">头像</label> <input type="file" name="headerImg" id="exampleInputFile"> </div> <div class="form-group"> <label for="exampleInputFile">生活照</label> <input type=" ...
git deploy遇到的问题
1. correct access rights
Please make sure you have the correct access rights and the repository exists.
原因:
公钥出问题了,需要删除.ssh下文件,然后重设置用户名和邮箱再重新生成ssh公钥即可解决
git遇到的问题之“Please make sure you have the correct access rights and the repository exists.”_jingtingfengguo的博客-CSDN博客
遇到这个错误大概率是因为ssh key有问题
解决步骤
1、删除.ssh下所有所有文件
2、重新在git设置一下身份的名字和邮箱
设置 name
git config --global user.name "yourname"
例如 git config --global user.name adorabled4
设置email
git config --global user.email“your@email.com"
例如git config --global user.email dhx2648466390@163.com
查看是否配置成功:
git config -list
3、git输入命令生成ssh-key
ssh-keygen -t rsa -C “your@email.com”(请填你设置的邮箱地址)
一路回车即可,
随后系统会自动在.ssh文件夹下生成两个文件,id_rsa和id_rsa.pub,用记事本打开id_rsa.pub ,将全部的内容复制
4、在github配置
完成
DP
⭐基础知识
代码随想录 (programmercarl.com)
什么是动态规划
动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。
所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,
动态规划的解题步骤
动态规划五部曲
确定dp数组(dp table)以及下标的含义
确定递推公式
dp数组如何初始化
确定遍历顺序
举例推导dp数组
动态规划应该如何debug
做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果。
然后再写代码,如果代码没通过就打印dp数组,看看是不是和自己预先推导的哪里不一样。
如果打印出来和自己预先模拟推导是一样的,那么就是自己的递归公式、初始化或者遍历顺序有问题了。
如果和自己预先模拟推导的不一样,那么就是代码实现细节有问题。
这样才是一个完整的思考过程,而不是一旦代码出问题,就毫无头绪的东改改西改改,最后过不了,或者说是稀里糊涂的过了。
👉day12
213. 打家劫舍 II
198. 打家劫舍 - 力扣(LeetCode)
和第 198 题的不同之处是,这道题中的房屋是首尾相连的,第一间房屋和最后一间房屋相邻,因此第一间房屋和最后一间房屋不能在同一晚上偷窃。
难度中等1148
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
打家劫舍 II(动态规划,结构化思路,清晰题解) - 打家劫舍 II - 力扣(LeetCode)
本题dp[i] 表示前i家人口能抢劫到的最大金额
递推公式: dp[i]=Math.max(dp[i]-1,dp[i-2]+nums[i]);
初始状态:
前 0间房子的最大偷窃价值为 00 ,即 dp[0] = 0 。
遍历顺序从左至右
以前三家为例 : (假设房屋总数大于3)
可以选择的 ...
day03 双指针
👉 day03 双指针
82. 删除排序链表中的重复元素 II
难度中等970
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
蛮力法
遍历链表 ,使用数组存储下每个值出现的次数, 然后再次遍历,
造一个新的链表, 返回即可
注意题目的数据 : -100<=val<=100
123456789101112131415161718192021class Solution { public ListNode deleteDuplicates(ListNode head) { if(head==null||head.next==null) return head; ListNode pre=new ListNode(-1); ListNode cur=head; int []nums=new int[200]; while(cur!=null){ nums[cur.val+100]++; cur=cur.next; } ListNode res=new ListNode(-1); head=res; for (int i = 0; i < nums.length; i++) { if(nums[i]==1){ res.next=new ListNode(i-100); res=res.next; } } return head.next; }}
🎈15. 三数之和
难度中等5138
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 *a,b,c ,*使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
**注意:**答案中不可以包含重复的三元组。
双指针
思路:
对数组进行排序
先设定一个前置的值
然后定义两个指针, 指向当前的值得后面的元素 l=i+1 , r=len-1 , 这里类似于二分的思想
...












