From a768168a5b85a26d097ab75b25b308f80dac1539 Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Sun, 4 Dec 2022 18:01:37 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dynamic/T10_FindTargetSumWays.java | 111 ++++++++++--- .../leecode/dynamic/T11_FindMaxForm.java | 156 ++++++++++++++++++ .../condition_monitoring/plot/test_plot.py | 20 +-- 3 files changed, 252 insertions(+), 35 deletions(-) create mode 100644 Leecode/src/main/java/com/markilue/leecode/dynamic/T11_FindMaxForm.java diff --git a/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java b/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java index db850cb..e1ae64e 100644 --- a/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java +++ b/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java @@ -1,26 +1,48 @@ 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题 难度中等: - * 给你一个整数数组 nums 和一个整数 target 。 - * 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : - * 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。 - * 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 + * @Description: TODO 力扣494题 目标和 难度中等: + * 给你一个整数数组 nums 和一个整数 target 。 + * 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : + * 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。 + * 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 * @Version: 1.0 */ 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,38 +52,77 @@ 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 */ public int findTargetSumWays(int[] nums, int target) { - int sum =0; + int sum = 0; 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; - - int[][] dp = new int[nums.length][left+1]; - - 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]; 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]; + } } diff --git a/Leecode/src/main/java/com/markilue/leecode/dynamic/T11_FindMaxForm.java b/Leecode/src/main/java/com/markilue/leecode/dynamic/T11_FindMaxForm.java new file mode 100644 index 0000000..cd63c19 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/dynamic/T11_FindMaxForm.java @@ -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大的那个数 + * 所以好像局部最优推不了全局最优? 贪心算法不行? + *

+ * 自己思路二:动态规划法: + * 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; + } + + +} diff --git a/TensorFlow_eaxmple/Model_train_test/condition_monitoring/plot/test_plot.py b/TensorFlow_eaxmple/Model_train_test/condition_monitoring/plot/test_plot.py index db646b7..8d15dda 100644 --- a/TensorFlow_eaxmple/Model_train_test/condition_monitoring/plot/test_plot.py +++ b/TensorFlow_eaxmple/Model_train_test/condition_monitoring/plot/test_plot.py @@ -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")