leecode更新

This commit is contained in:
markilue 2022-12-04 18:01:37 +08:00
parent 8a335ef25a
commit a768168a5b
3 changed files with 252 additions and 35 deletions

View File

@ -1,12 +1,13 @@
package com.markilue.leecode.dynamic; package com.markilue.leecode.dynamic;
import org.junit.Test;
/** /**
* @BelongsProject: Leecode * @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.dynamic * @BelongsPackage: com.markilue.leecode.dynamic
* @Author: markilue * @Author: markilue
* @CreateTime: 2022-11-25 19:51 * @CreateTime: 2022-11-25 19:51
* @Description: * @Description: TODO 力扣494题 目标和 难度中等
* TODO 力扣494题 难度中等
* 给你一个整数数组 nums 和一个整数 target * 给你一个整数数组 nums 和一个整数 target
* 向数组中的每个整数前添加 '+' '-' 然后串联起所有整数可以构造一个 表达式 * 向数组中的每个整数前添加 '+' '-' 然后串联起所有整数可以构造一个 表达式
* 例如nums = [2, 1] 可以在 2 之前添加 '+' 1 之前添加 '-' 然后串联起来得到表达式 "+2-1" * 例如nums = [2, 1] 可以在 2 之前添加 '+' 1 之前添加 '-' 然后串联起来得到表达式 "+2-1"
@ -15,12 +16,33 @@ package com.markilue.leecode.dynamic;
*/ */
public class T10_FindTargetSumWays { 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所以还是可以转为背包问题 * 代码随想录尝试动态规划法:本题要如何使表达式结果为target既然为target那么就一定有 left组合 - right组合 = target所以还是可以转为背包问题
* left + right等于sum而sum是固定的公式来了 left - (sum - left) = target -> left = (target + sum)/2 此时问题就是在集合nums中找出和为left的组合 * left + right等于sum而sum是固定的公式来了 left - (sum - left) = target -> left = (target + sum)/2 此时问题就是在集合nums中找出和为left的组合
* TODO 也就是说可以转为填满背包大小为left有几种方法这与之前的背包问题不同之前都是求容量为j的背包最多能装多少 * TODO 也就是说可以转为填满背包大小为left有几种方法这与之前的背包问题不同之前都是求容量为j的背包最多能装多少
* TODO 动态规划五部曲: * 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数组的状态转移方程: * 2)dp数组的状态转移方程:
* 例如dp[j]j 为5 * 例如dp[j]j 为5
* 已经有一个1nums[i] 的话 dp[4]种方法 凑成 dp[5] * 已经有一个1nums[i] 的话 dp[4]种方法 凑成 dp[5]
@ -30,38 +52,77 @@ public class T10_FindTargetSumWays {
* 已经有一个5 nums[i]的话 dp[0]中方法 凑成 dp[5] * 已经有一个5 nums[i]的话 dp[0]中方法 凑成 dp[5]
* 所以求组合类问题的公式都是类似这种 * 所以求组合类问题的公式都是类似这种
* dp[j] += dp[j - nums[i]] * dp[j] += dp[j - nums[i]]
* 3)dp数组初始化: dp[0] = 1理论上也很好解释装满容量为0的背包有1种方法就是装0件物品 * 对于二维dpdp[i][j] = dp[i-1][j]+dp[i-1][j-num[i]];
* 4)dp数组的遍历顺序: * 可以理解为对于新增num[i]来凑i时我可以选择不要num[i]直接用以前的来凑也可以选择使用num[i],那么以前的数据需要凑j-num[i]
* 5)dp的举例推导:当nums=[1,1,1,1,1],target=3时 * 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] * [0 1 2 3 4]
* i=0 0 1 1 1 1 * i=0 1 1 0 0 0
* i=1 0 1 2 2 2 * i=1 1 2 1 0 0
* i=2 0 1 2 3 3 * i=2 1 3 3 1 0
* i=3 0 1 2 3 4 * i=3 1 4 6 4 1
* i=4 0 1 2 3 4 * i=4 1 5 10 10 5
*二维dp速度击败59.54%内存击败25.85% 3ms
* @param nums * @param nums
* @param target * @param target
* @return * @return
*/ */
public int findTargetSumWays(int[] nums, int target) { public int findTargetSumWays(int[] nums, int target) {
int sum =0; int sum = 0;
for (int i = 0; i < nums.length; i++) { for (int i = 0; i < nums.length; i++) {
sum+=nums[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的情况即要不要都是这个数
} }
int left = (sum+target)/2; }
for (int i = 1; i < dp.length; i++) {
int[][] dp = new int[nums.length][left+1];
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j <= left; j++) { for (int j = 0; j <= left; j++) {
if(j<nums[i]) dp[i][j]=dp[i-1][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];
}
} }

View File

@ -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;
}
}

View File

@ -468,12 +468,12 @@ def plot_FNR2(y_data):
# x2_width = [i + 0.3 for i in x_width] # 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[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[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-4", 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-5", 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-34", 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-35", 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-45", 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] + 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[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') 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] # 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) # test_bar(list)
list=[98.56,98.95,99.95,96.1,95,99.65,76.25,72.64,75.87,68.74] # list=[98.56,98.95,99.95,96.1,95,99.65,76.25,72.64,75.87,68.74]
plot_FNR1(list) # plot_FNR1(list)
# # # #
# list=[3.43,1.99,1.92,2.17,1.63,1.81,1.78,1.8,0.6] list=[3.43,1.99,1.92,2.17,1.63,1.81,1.78,1.8,0.6]
# plot_FNR2(list) plot_FNR2(list)
# 查看网络某一层的权重 # 查看网络某一层的权重
# test_model_visualization(model_name = "E:\跑模型\论文写作/SE.txt") # test_model_visualization(model_name = "E:\跑模型\论文写作/SE.txt")