leecode更新
This commit is contained in:
parent
8a335ef25a
commit
a768168a5b
|
|
@ -1,12 +1,13 @@
|
|||
package com.markilue.leecode.dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
* @BelongsPackage: com.markilue.leecode.dynamic
|
||||
* @Author: markilue
|
||||
* @CreateTime: 2022-11-25 19:51
|
||||
* @Description:
|
||||
* TODO 力扣494题 难度中等:
|
||||
* @Description: TODO 力扣494题 目标和 难度中等:
|
||||
* 给你一个整数数组 nums 和一个整数 target 。
|
||||
* 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
|
||||
* 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
|
||||
|
|
@ -15,12 +16,33 @@ package com.markilue.leecode.dynamic;
|
|||
*/
|
||||
public class T10_FindTargetSumWays {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {1, 1, 1, 1, 1};
|
||||
int target = 3;
|
||||
System.out.println(findTargetSumWays(nums, target));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
int[] nums = {0,0,0,0,0,0,0,0,1};
|
||||
int target = 1;
|
||||
System.out.println(findTargetSumWays(nums, target));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
int[] nums = {1};
|
||||
int target = 2;
|
||||
System.out.println(findTargetSumWays(nums, target));
|
||||
}
|
||||
/**
|
||||
* 代码随想录尝试动态规划法:本题要如何使表达式结果为target。既然为target,那么就一定有 left组合 - right组合 = target。所以还是可以转为背包问题
|
||||
* left + right等于sum,而sum是固定的。公式来了, left - (sum - left) = target -> left = (target + sum)/2 。此时问题就是在集合nums中找出和为left的组合。
|
||||
* TODO 也就是说可以转为填满背包大小为left有几种方法。这与之前的背包问题不同。之前都是求容量为j的背包最多能装多少,
|
||||
* TODO 动态规划五部曲:
|
||||
* 1)dp数组的定义: dp[i][j] 满j(包括j)这么大容积的包,有dp[j]种方法: 使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。
|
||||
* 1)dp数组的定义: dp[i][j] 满j(包括j)这么大容积的包,有dp[j]种方法: 使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。 注意这里是刚好凑满
|
||||
* 2)dp数组的状态转移方程:
|
||||
* 例如:dp[j],j 为5,
|
||||
* 已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 dp[5]。
|
||||
|
|
@ -30,15 +52,19 @@ public class T10_FindTargetSumWays {
|
|||
* 已经有一个5 (nums[i])的话,有 dp[0]中方法 凑成 dp[5]
|
||||
* 所以求组合类问题的公式,都是类似这种:
|
||||
* dp[j] += dp[j - nums[i]]
|
||||
* 3)dp数组初始化: dp[0] = 1,理论上也很好解释,装满容量为0的背包,有1种方法,就是装0件物品。
|
||||
* 4)dp数组的遍历顺序:
|
||||
* 5)dp的举例推导:当nums=[1,1,1,1,1],target=3时
|
||||
* 对于二维dp:dp[i][j] = dp[i-1][j]+dp[i-1][j-num[i]];
|
||||
* 可以理解为:对于新增num[i]来凑i时我可以选择不要num[i]直接用以前的来凑,也可以选择使用num[i],那么以前的数据需要凑j-num[i]
|
||||
* 3)dp数组初始化: dp[0] = 1,理论上也很好解释,装满容量为0的背包,有1种方法,就是装0件物品;
|
||||
* 对于二维的初始化可以考虑dp[i][0]=1,即全部要就凑i一种方法,而dp[0][j] = i==num[i]? 1:0;即我只有可以使用num[i]刚好来凑i才可以
|
||||
* 4)dp数组的遍历顺序:,nums放在外循环,target在内循环,且内循环倒序。
|
||||
* 5)dp的举例推导:当nums=[1,1,1,1,1],target=3时 left=(3+5)/2=4
|
||||
* [0 1 2 3 4]
|
||||
* i=0 0 1 1 1 1
|
||||
* i=1 0 1 2 2 2
|
||||
* i=2 0 1 2 3 3
|
||||
* i=3 0 1 2 3 4
|
||||
* i=4 0 1 2 3 4
|
||||
* i=0 1 1 0 0 0
|
||||
* i=1 1 2 1 0 0
|
||||
* i=2 1 3 3 1 0
|
||||
* i=3 1 4 6 4 1
|
||||
* i=4 1 5 10 10 5
|
||||
*二维dp速度击败59.54%,内存击败25.85% 3ms
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
|
|
@ -49,19 +75,54 @@ public class T10_FindTargetSumWays {
|
|||
for (int i = 0; i < nums.length; i++) {
|
||||
sum += nums[i];
|
||||
}
|
||||
|
||||
if ((target + sum) % 2 != 0) return 0;
|
||||
int left = (sum + target) / 2;
|
||||
|
||||
left = left<0? -left:left; //防止是负数,索引超出限制
|
||||
int[][] dp = new int[nums.length][left + 1];
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
dp[i][0]=1;
|
||||
}
|
||||
for (int i = 0; i < left + 1; i++) {
|
||||
if(nums[0]==i){
|
||||
dp[0][i]+=1; //注意这里要从0开始,而且是+= 防止里面的数可能是0的情况,即要不要都是这个数
|
||||
}
|
||||
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
}
|
||||
for (int i = 1; i < dp.length; i++) {
|
||||
for (int j = 0; j <= left; j++) {
|
||||
if (j < nums[i]) dp[i][j] = dp[i - 1][j] ;
|
||||
else dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
|
||||
else dp[i][j] = dp[i - 1][j] + dp[i-1][j - nums[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return dp[nums.length-1][left];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 代码随想录一维dp动态规划法:
|
||||
* 速度击败94.39%,内存击败67.26% 2ms
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int findTargetSumWays1(int[] nums, int target) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < nums.length; i++) sum += nums[i];
|
||||
if ((target + sum) % 2 != 0) return 0;
|
||||
int size = (target + sum) / 2;
|
||||
if (size < 0) size = -size;
|
||||
int[] dp = new int[size + 1];
|
||||
dp[0] = 1;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
for (int j = size; j >= nums[i]; j--) {
|
||||
System.out.println("dp[j]:"+dp[j]);
|
||||
System.out.println("dp[j - nums[i]]:"+dp[j - nums[i]]);
|
||||
System.out.println("=======================================");
|
||||
dp[j] += dp[j - nums[i]];
|
||||
}
|
||||
}
|
||||
return dp[size];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
package com.markilue.leecode.dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
* @BelongsPackage: com.markilue.leecode.dynamic
|
||||
* @Author: markilue
|
||||
* @CreateTime: 2022-12-04 16:32
|
||||
* @Description: TODO 力扣474题 一和零:
|
||||
* 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
|
||||
* 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。
|
||||
* 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class T11_FindMaxForm {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] strs = {"10", "0001", "111001", "1", "0"};
|
||||
int m = 5;
|
||||
int n = 3;
|
||||
System.out.println(findMaxForm(strs, m, n));
|
||||
}
|
||||
|
||||
/**
|
||||
* 自己思路:这题的最多最长等词眼感觉很贪心,所以浅试一下贪心算法:
|
||||
* 贪心算法思路:先按子元素长度排序,优先选长度短的,但是长度短不意味着0 和1都少?
|
||||
* 如果一个子集是‘111’ 另两个是‘1001’ 和 ‘10’,所以当长度相同的时候尽量选 m和n大的那个数
|
||||
* 所以好像局部最优推不了全局最优? 贪心算法不行?
|
||||
* <p>
|
||||
* 自己思路二:动态规划法:
|
||||
* TODO 五部曲:
|
||||
* (1)dp定义: dp[k][i][j]表示使用string[0-k]时最多能容纳i个0和j个1的背包的最大子集长度
|
||||
* (2)dp数组递推公式: 这一个dp[i][j]可以表示要这个数时dp[k-1][i-string[k]m][j-string[k]n]+1,和不要这个数时dp[k-1][i][j];
|
||||
* dp[k][i][j]=max(dp[k-1][i-string[k]m][j-string[k]n]+1,dp[k-1][i][j])
|
||||
* (3)dp的初始化:dp[k][0][0]=0当i和j都为0时子集只能为空
|
||||
* (4)dp遍历顺序:从(2)来看需要从前往后遍历
|
||||
* (5)举例推导:
|
||||
* 速度击败17.98%,内存击败5.2%
|
||||
* @param strs
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int findMaxForm(String[] strs, int m, int n) {
|
||||
int[][][] dp = new int[strs.length][m + 1][n + 1];
|
||||
|
||||
//初始化
|
||||
|
||||
int zeroNum = 0;
|
||||
int oneNum = 0;
|
||||
for (char c : strs[0].toCharArray()) {
|
||||
if (c == '0') zeroNum++;
|
||||
else oneNum++;
|
||||
}
|
||||
//遍历m
|
||||
for (int j = 0; j < m + 1; j++) {
|
||||
//遍历n
|
||||
for (int k = 0; k < n + 1; k++) {
|
||||
if (j < zeroNum || k < oneNum) dp[0][j][k] = 0;
|
||||
else dp[0][j][k] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//遍历子元素
|
||||
for (int i = 1; i < strs.length; i++) {
|
||||
zeroNum = 0;
|
||||
oneNum = 0;
|
||||
for (char c : strs[i].toCharArray()) {
|
||||
if (c == '0') zeroNum++;
|
||||
else oneNum++;
|
||||
}
|
||||
//遍历m
|
||||
for (int j = 0; j < m + 1; j++) {
|
||||
//遍历n
|
||||
for (int k = 0; k < n + 1; k++) {
|
||||
if (j < zeroNum || k < oneNum) dp[i][j][k] = dp[i - 1][j][k];
|
||||
else dp[i][j][k] = Math.max(dp[i - 1][j - zeroNum][k - oneNum] + 1, dp[i - 1][j][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[strs.length - 1][m][n];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dp数组简化为一个二维数组后
|
||||
* 速度击败63.62% 内存击败41.28% 18ms
|
||||
* @param strs
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int findMaxForm1(String[] strs, int m, int n) {
|
||||
//dp[i][j]表示i个0和j个1时的最大子集
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
int oneNum, zeroNum;
|
||||
for (String str : strs) {
|
||||
oneNum = 0;
|
||||
zeroNum = 0;
|
||||
for (char ch : str.toCharArray()) {
|
||||
if (ch == '0') {
|
||||
zeroNum++;
|
||||
} else {
|
||||
oneNum++;
|
||||
}
|
||||
}
|
||||
//倒序遍历
|
||||
for (int i = m; i >= zeroNum; i--) {
|
||||
for (int j = n; j >= oneNum; j--) {
|
||||
dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方二维dp解法:
|
||||
* 看起来比代码随想录快在不需要一直给zero和one进行初始化
|
||||
* 速度击败97.36% 内存50.2%
|
||||
*
|
||||
* @param strs
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int findMaxForm2(String[] strs, int m, int n) {
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
int length = strs.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int[] zerosOnes = getZerosOnes(strs[i]);
|
||||
int zeros = zerosOnes[0], ones = zerosOnes[1];
|
||||
for (int j = m; j >= zeros; j--) {
|
||||
for (int k = n; k >= ones; k--) {
|
||||
dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
|
||||
public int[] getZerosOnes(String str) {
|
||||
int[] zerosOnes = new int[2];
|
||||
int length = str.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
zerosOnes[str.charAt(i) - '0']++;
|
||||
}
|
||||
return zerosOnes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -468,12 +468,12 @@ def plot_FNR2(y_data):
|
|||
# x2_width = [i + 0.3 for i in x_width]
|
||||
|
||||
plt.bar(x_width[0], y_data[0], lw=1, color=['#FAF4E1'], width=0.5 * 2 / 3, label="ResNet-18", edgecolor='black')
|
||||
plt.bar(x_width[1], y_data[1], lw=1, color=['#F5E3C4'], width=0.5 * 2 / 3, label="RNet-3", edgecolor='black')
|
||||
plt.bar(x_width[2], y_data[2], lw=1, color=['#EBC99D'], width=0.5 * 2 / 3, label="RNet-4", edgecolor='black')
|
||||
plt.bar(x_width[3], y_data[3], lw=1, color=['#FFC79C'], width=0.5 * 2 / 3, label="RNet-5", edgecolor='black')
|
||||
plt.bar(x_width[4], y_data[4], lw=1, color=['#D6E6F2'], width=0.5 * 2 / 3, label="RNet-34", edgecolor='black')
|
||||
plt.bar(x_width[5], y_data[5], lw=1, color=['#B4D1E9'], width=0.5 * 2 / 3, label="RNet-35", edgecolor='black')
|
||||
plt.bar(x_width[6], y_data[6], lw=1, color=['#AEB5EE'], width=0.5 * 2 / 3, label="RNet-45", edgecolor='black')
|
||||
plt.bar(x_width[1], y_data[1], lw=1, color=['#F5E3C4'], width=0.5 * 2 / 3, label="RNet-1", edgecolor='black')
|
||||
plt.bar(x_width[2], y_data[2], lw=1, color=['#EBC99D'], width=0.5 * 2 / 3, label="RNet-2", edgecolor='black')
|
||||
plt.bar(x_width[3], y_data[3], lw=1, color=['#FFC79C'], width=0.5 * 2 / 3, label="RNet-3", edgecolor='black')
|
||||
plt.bar(x_width[4], y_data[4], lw=1, color=['#D6E6F2'], width=0.5 * 2 / 3, label="RNet-12", edgecolor='black')
|
||||
plt.bar(x_width[5], y_data[5], lw=1, color=['#B4D1E9'], width=0.5 * 2 / 3, label="RNet-13", edgecolor='black')
|
||||
plt.bar(x_width[6], y_data[6], lw=1, color=['#AEB5EE'], width=0.5 * 2 / 3, label="RNet-23", edgecolor='black')
|
||||
# plt.bar(x_width[7] + 2.0, y_data[10], lw=0.5, color=['#8085e9'], width=1, label="ResNet-18", edgecolor='black')
|
||||
plt.bar(x_width[7], y_data[7], lw=1, color=['#D5A9FF'], width=0.5 * 2 / 3, label="ResNet-C", edgecolor='black')
|
||||
plt.bar(x_width[8], y_data[8], lw=1, color=['#E000F5'], width=0.5 * 2 / 3, label="JMNet", edgecolor='black')
|
||||
|
|
@ -781,11 +781,11 @@ if __name__ == '__main__':
|
|||
# list = [3.77, 2.64, 2.35, 2.05, 1.76, 1.09, 0.757, 0.82, 1.1, 0.58, 0, 0.03, 0.02]
|
||||
# test_bar(list)
|
||||
|
||||
list=[98.56,98.95,99.95,96.1,95,99.65,76.25,72.64,75.87,68.74]
|
||||
plot_FNR1(list)
|
||||
# list=[98.56,98.95,99.95,96.1,95,99.65,76.25,72.64,75.87,68.74]
|
||||
# plot_FNR1(list)
|
||||
# #
|
||||
# list=[3.43,1.99,1.92,2.17,1.63,1.81,1.78,1.8,0.6]
|
||||
# plot_FNR2(list)
|
||||
list=[3.43,1.99,1.92,2.17,1.63,1.81,1.78,1.8,0.6]
|
||||
plot_FNR2(list)
|
||||
|
||||
# 查看网络某一层的权重
|
||||
# test_model_visualization(model_name = "E:\跑模型\论文写作/SE.txt")
|
||||
|
|
|
|||
Loading…
Reference in New Issue