Leetcode百題斬-DP

又到了最好玩的dp了,各種玄學轉移也算是其樂無窮。前段時間剛做的LCA正是這種題的小試牛刀,如果當時就把這個專題刷完了,或許我現在已經從西溪園區跑到云谷園區了。

不過,恐怖如斯的dp專題居然只給了一道hard,基本也沒啥難度可言了。看部分題目之前也刷過,但也沒怎么記錄在博客里,這次統一再刷一遍,快速過掉。部分題深挖一下倒也可以溫習一些旁路的知識點

二維

先看二維,理論上二維要比一維要好想一點

5. Longest Palindromic Substring[Medium]

思路:這題就是之前通義實驗室出的面試題,雖然有dp做法,但中心擴散法和終極Manachar算法還是挺有趣的。由于是幾個月前剛做的,這里就不贅述了,感興趣可以往前翻

多學一點:馬拉車算法

最長回文子序列-CSDN博客

64. Minimum Path Sum[Medium]

思路:求矩陣左上到右下的最小路徑和,這種矩陣的求和是最經典的dp了,直接左上兩格轉移即可

/*
Author Owen_Q
*/
public class MinimumPathSum {public static int minPathSum(int[][] grid) {int m = grid.length;int n = grid[0].length;int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i == 0 && j == 0) {dp[i][j] = grid[i][j];} else if (i == 0) {dp[i][j] = dp[i][j - 1] + grid[i][j];} else if (j == 0) {dp[i][j] = dp[i - 1][j] + grid[i][j];} else {dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];}}}return dp[m - 1][n - 1];}
}

72. Edit Distance[Medium]

思路:單詞變更和矩陣題類似,也十分容易出dp類型的題,以新舊兩個單詞的長度作為dp維度,每次變更一位進行轉移,那么增,刪,改分別剛好對應了左,上和左上三個轉移區域。針對改特判一下若尾部相同則可以不進行修改即可。

/*
Author Owen_Q
*/
public class WordsDistance {public static int minDistance(String word1, String word2) {int m = word1.length();int n = word2.length();int[][] dp = new int[m + 1][n + 1];for (int i = 0; i <= m; i++) {for (int j = 0; j <= n; j++) {if (i == 0) {dp[i][j] = j;} else if (j == 0) {dp[i][j] = i;} else {dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]);if (word1.charAt(i - 1) == word2.charAt(j - 1)) {dp[i][j] = Math.min(dp[i - 1][j - 1], dp[i][j]);} else {dp[i][j] = Math.min(dp[i - 1][j - 1] + 1, dp[i][j]);}}}}return dp[m][n];}
}

1143. Longest Common Subsequence[Medium]

思路:經典二維dp問題,LCS,話不多說直接上代碼

/*
Author Owen_Q
*/
public class LongestCommonSequence {public static int longestCommonSubsequence(String text1, String text2) {int n = text1.length();int m = text2.length();int[][] dp = new int[n + 1][m + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (text1.charAt(i - 1) == text2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[n][m];}
}

?118. Pascal's Triangle[Easy]

思路:楊輝三角來咯

/*
Author Owen_Q
*/
public class PascalTriangle {public static List<List<Integer>> generate(int numRows) {List<List<Integer>> result = new ArrayList<>();int[][] dp = new int[numRows][numRows];for (int i = 0; i < numRows; i++) {List<Integer> rowResult = new ArrayList<>();for (int j = 0; j <= i; j++) {if (j == 0 || j == i) {dp[i][j] = 1;} else {dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];}rowResult.add(dp[i][j]);}result.add(rowResult);}return result;}
}

多學一點:組合數性質

比較有意思的就是,楊輝三角的值剛好對應了組合數的值,即楊輝三角的第n行第m列剛好是組合數的?c_{n}^{m}=\frac{n!}{m!\times (n-m)!}。這剛好對應了組合數的性質,即 c_{n}^{m} = c_{n-1}^{m} +c_{n-1}^{m-1}。此外,楊輝三角的每一行也剛好就是?(a+b)^{n}?二項展開式中的系數

62. Unique Paths[Medium]

思路:求矩陣左上到右下的路徑數量,和上述編號64題極其類似,上面是求最小最小值,這里是求和,換湯不換藥

/*
Author Owen_Q
*/
public class UniquePaths {public static int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i == 0 && j == 0) {dp[i][j] = 1;} else if (i == 0) {dp[i][j] = dp[i][j - 1];} else if (j == 0) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}}return dp[m - 1][n - 1];}
}

一維?

接下來看看一維,其實一維也很簡單,leetcode真的很良心了,基本毫無難度

152. Maximum Product Subarray[Medium]

思路:求數串的最大子串乘積,其實可以不用dp,在不考慮符號的情況下,乘積肯定是越乘越大,考慮符號,那么記錄一下當前最大乘積和最小乘積,每次遇到零則清空一下即可。最后注意一下單個數字的場景,這種情況下該數字即為最大乘積,而非初始化的0,特判一下即可;

/*
Author Owen_Q
*/
public class MaximumProductSubarray {public static void main(String[] args) {System.out.println(maxProduct(new int[] {2, 3, -2, 4}));System.out.println(maxProduct(new int[] {-2, 0, -1}));System.out.println(maxProduct(new int[] {-2}));System.out.println(maxProduct(new int[] {-4, -3, -2}));}public static int maxProduct(int[] nums) {if (nums.length == 1) {return nums[0];}int result = nums[0];int curMaxProduct = 0;int curMinProduct = 0;for (int num : nums) {if (num == 0) {curMaxProduct = 0;curMinProduct = 0;} else if (num > 0) {curMaxProduct = Math.max(curMaxProduct * num, num);curMinProduct = Math.min(curMinProduct * num, num);} else {int preMaxProduct = curMaxProduct;curMaxProduct = Math.max(curMinProduct * num, num);curMinProduct = Math.min(preMaxProduct * num, num);}//System.out.println(num + "*" + curMaxProduct + "*" + curMinProduct);result = Math.max(result, curMaxProduct);}return result;}
}

279. Perfect Squares[Medium]

思路:給定某個數,求當前數最少可以由多少個完全平方數求和而來。那么這個dp思路也很好想,每個數由其減去一個完全平方數轉移而來,即?dp[i] = min(dp[i-k^{2}]+1), k^{2} <= i

/*
Author Owen_Q
*/
public class PerfectSquares {public static int numSquares(int n) {int[] dp = new int[n + 1];for (int i = 0; i <= n; i++) {dp[i] = i;for (int j = 1; j * j <= i; j++) {dp[i] = Math.min(dp[i], dp[i - j * j] + 1);}}return dp[n];}
}

多學一點:四平方和定理

上述遞推的時間復雜度為O(n\sqrt{n}),對于大數會有很大的消耗。因此如果有數學方法進行優化,那將大大降低時間復雜度。這里我們引入拉格朗日的四平方數定理的,即:任何一個正整數都可以表示為至多四個正整數的平方和。這個定理一下就把這題的值域縮小到了?[1,4],這四個整數內。進一步了解,在四平方和定理的基礎上,還有一個更嚴格的定理,就是勒讓德的三平方和定理,即:當且僅當?n= 4^{k}\times (8m+7)?時,n可以被表示為四個正整數的平方。那么,當?n\neq 4^{k}\times (8m+7)?時,答案的數量又被縮小到?[1,3]。于是直接特判即可。針對答案為1的場景,n為完全平方式。針對答案為2的場景,n=a^{2}+b^{2},那么枚舉a,如果?b=n-a^{2}?為完全平方數,則成立。最后,若1和2均不滿足,則答案為3。于是,利用平方定理,最大的時間耗時就是在判斷答案是否為2這條分支上,于是整體的時間復雜度就被降到了O(\sqrt{n})

/*
Author Owen_Q
*/
public class PerfectSquares {public static int numSquaresWithMaths(int n) {if (foutSquares(n)) {return 4;}if (perfectSquares(n)) {return 1;}if (twoSquares(n)) {return 2;}return 3;}private static boolean foutSquares(int n) {while (n % 4 == 0) {n /= 4;}return n % 8 == 7;}private static boolean perfectSquares(int n) {int sqrtn = (int)Math.sqrt(n);return sqrtn * sqrtn == n;}private static boolean twoSquares(int n) {for (int i = 1; i * i < n; i++) {if (perfectSquares(n - i * i)) {return true;}}return false;}
}

直接登頂

70. Climbing Stairs[Easy]

思路:不愧是easy題,斐波那契數組和楊輝三角堪稱dp屆的始祖。這題就是斐波那契數組,直接求

/*
Author Owen_Q
*/
public class ClimbingStairs {public static int climbStairs(int n) {int[] dp = new int[n + 1];dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

多學一點:矩陣快速冪

一提到斐波那契,怎么能沒有矩陣快速冪。

基礎遞推01-CSDN博客

首先,觀察通項公式

dp[n] = dp[n-1]+dp[n-2]

將通項公式轉化到矩陣中,可以得到矩陣的遞推關系

\begin{bmatrix} dp[n]\\ dp[n-1] \end{bmatrix}=\begin{bmatrix} dp[n-1]+dp[n-2]\\ dp[n-1] \end{bmatrix}=\begin{bmatrix} 1\times dp[n-1]+1\times dp[n-2]\\ 1\times dp[n-1] + 0\times dp[n-2] \end{bmatrix}=\begin{bmatrix} 1& 1\\ 1 & 0 \end{bmatrix}\begin{bmatrix} dp[n-1]\\ dp[n-2] \end{bmatrix}=\begin{bmatrix} 1& 1\\ 1 & 0 \end{bmatrix}^{k}\begin{bmatrix} dp[n-k]\\ dp[n-k-1] \end{bmatrix} =\begin{bmatrix} 1& 1\\ 1 & 0 \end{bmatrix}^{n-1}\begin{bmatrix} dp[1]\\ dp[0] \end{bmatrix}

于是,O(n)?的遞推線性復雜度就被降為了?O(logn)?的求矩陣冪的復雜度

/*
Author Owen_Q
*/
public class ClimbingStairs {public static int climbStairsWithBinaryExponentiation(int n) {int[][] a = {{1, 1}, {1, 0}};return power(a, n)[0][0];}private static int[][] power(int[][] a, int n) {if (a == null) {return null;}int len = a.length;int size = a[0].length;if (len != size) {return null;}int[][] result = {{1, 0}, {0, 1}};while (n > 0) {if ((n & 1) == 1) {result = multiple(result, a);}a = multiple(a, a);n >>= 1;}return result;}private static int[][] multiple(int[][] a, int[][] b) {int alen = a.length;int blen = b.length;int asize = a[0].length;int bsize = b[0].length;if (asize != blen) {return null;}int c[][] = new int[alen][bsize];for (int i = 0; i < alen; i++) {for (int j = 0; j < bsize; j++) {c[i][j] = 0;for (int k = 0; k < asize; k++) {c[i][j] += a[i][k] * b[k][j];}}}return c;}
}

再衍生一步,其實任何線性其次遞推公式都可以用矩陣快速冪來優化

針對m項遞推?f(n)=\sum_{i=1}^{m}a_{i}\times f(n-i)?,都可以構造m \times m的矩陣\begin{bmatrix} a_{1}& a_{2}& a_{3}& ...& a_{m-1}& a_{m}\\ 1& 0 & 0 & ... & 0 & 0\\ 0& 1& 0 &... &0 &0 \\ 0& 0 & 1 & ... & 0 & 0\\ ...& ... & ... & ... & ... & ...\\ 0& 0 &0 &... & 1 & 0 \end{bmatrix}

然后即可基于矩陣快速冪進行計算,而對應的單位矩陣即為

\begin{bmatrix} 1& 0 & 0 & ... & 0\\ 0& 1& 0 &... &0 \\ 0& 0 & 1 & ... & 0\\ ...& ... & ... & ... & ...\\ 0& 0 &0 &... & 1 \end{bmatrix}

198. House Robber[Medium]

思路:選物品,每個物品有一定價值,不占容量,但不可連續選擇,求最大物品數。這像是個低配版背包,直接相鄰轉移即可

/*
Author Owen_Q
*/
public class HorseRobber {public static int rob(int[] nums) {int n = nums.length;int[] dp = new int[n + 1];dp[0] = 0;dp[1] = nums[0];for (int i = 2; i <= n; i++) {dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);}return dp[n];}
}

300. Longest Increasing Subsequence[Medium]

思路:經典LIS問題,最長單增子序列,不多說直接求

/*
Author Owen_Q
*/
public class LongestIncreasingSubsequence {public static int lengthOfLIS(int[] nums) {int n = nums.length;int[] dp = new int[n];dp[0] = 1;int re = 1;for (int i = 1; i < n; i++) {dp[i] = 1;for (int j = 0; j < i; j++) {if (nums[j] < nums[i]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}re = Math.max(dp[i], re);}return re;}
}

多學一點:貪心?

這么經典的問題,當然不能用DP,這平方級別的復雜度,當然要想著優化一下。

這里用到一個神奇的思路,就是轉換狀態和狀態值

原先?dp[i]?表示結尾為?num[i]?的最長單增子序列的長度

那么這次引入新的數組?g[i]?表示長度為?i?的最長單增子序列的最小結尾值。

不難發現,g[i]?一定是單增的。比如,某長度為i的最長公共子序列,最后一位為?g[i]?刪去最后一位后,倒數第二位一定大于等于?g[i-1],因為若倒數第二位小于?g[i-1],那么這個數自身就可以更新?g[i-1]?使得值更小。于是這題就變成了貪心求?g[i]

具體貪心的過程即是,遍歷數組,針對每個新的數,找到g數組中大于當前數的首個位置,若沒有找到,則將當前數塞到g數組末尾。否則,更新找到的位置為當前數。至于找到首個大于當前數的位置,可以直接用二分來實現,最終能將時間內復雜度降到?O(nlogn)

下面來說一下二分搜索。java中有現成的函數 java.util.Collections#binarySearch(java.util.List<? extends java.lang.Comparable<? super T>>, T),要求傳入的數組一定為有序的。返回值分為兩種,若為正數,則說明當前值已找到,返回的結果即為當前值在數組中的位置。若返回值為負數,則表示當前值未找到,返回的結果為當前值可插入的位置-1

/*
Author Owen_Q
*/
public class LongestIncreasingSubsequence {public static int lengthOfLISGreedy(int[] nums) {List<Integer> g = new ArrayList<>();for (int num : nums) {int searchResult = Collections.binarySearch(g, num);if (searchResult < 0) {searchResult = searchResult * -1 - 1;if (searchResult == g.size()) {g.add(num);} else {g.set(searchResult, num);}}}return g.size();}
}

效果拔群?

322. Coin Change[Medium]

思路:提到DP,怎么能沒有背包呢!典型的背包問題,由于硬幣的數量無限,那么這就是個完全背包問題,轉移時從小向大遍歷。如果這題每種硬幣只能取一個,那就變成了最基礎的01背包問題,從大向小遍歷即可。背包做完舒服了

/*
Author Owen_Q
*/
public class CoinChange {public static int coinChange(int[] coins, int amount) {int[] dp = new int[amount + 1];Arrays.fill(dp, -1);dp[0] = 0;for (int coin : coins) {for (int i = 1; i <= amount; i++) {if (i >= coin && dp[i - coin] >= 0) {if (dp[i] == -1) {dp[i] = dp[i - coin] + 1;} else {dp[i] = Math.min(dp[i], dp[i - coin] + 1);}}}}return dp[amount];}
}

416. Partition Equal Subset Sum[Medium]

思路:給定一個數組,求能否將數組中的數均勻分成兩塊。由于數組中的數字不可分,那么又可以轉換為背包問題。每個數均只有一個,可以用01背包。這題由于只需要求可行性,因此,直接將初始dp默認為1,別的均初始化為0,然后設置背包容量為數組和的一半,通過最大值進行轉移看最終能否將1轉移到半背包容量的位置處

/*
Author Owen_Q
*/
public class PartitionEqualSubsetSum {public static boolean canPartition(int[] nums) {int sum = 0;for (int num : nums) {sum += num;}if (sum % 2 == 1) {return false;}sum >>= 1;int[] dp = new int[sum + 1];dp[0] = 1;for (int num : nums) {for (int i = sum; i >= num; i--) {dp[i] = Math.max(dp[i], dp[i - num]);}}return dp[sum] == 1;}
}

139. Word Break[Medium]

思路:判斷某個字符串是否可以被分割為多個特定字典中的單詞。當然想到dp,表示當前位置為止的前綴是否滿足要求。轉移方程就是往前遍歷,找到前面滿足的位置,再判斷從找到的位置到當前位置中的字符串是否能在字典中尋找到,即?dp[i]=dp[j]\wedge word[j,i)

/*
Author Owen_Q
*/
public class WordBreak {public static boolean wordBreak(String s, List<String> wordDict) {int len = s.length();boolean[] dp = new boolean[len + 1];dp[0] = true;for (int i = 1; i <= len; i++) {for (int j = 0; j < i; j++) {if (wordDict.contains(s.substring(j, i)) && dp[j]) {dp[i] = true;break;}}}return dp[len];}
}

多學一點:字典樹(Trie)

不難發現dp轉移過程中,有很多無用的轉移,比如當當前字典中沒有以當前字母為開頭的字段時,就可以停止這輪轉移。甚至更進一步,當當前字典中沒有以當前搜索的區域為前綴的字段時,就可以停止繼續搜索了。

還記得之前特地有個專題說到了前綴問題的數據結構字典樹嗎,這不就用上了

Leetcode百題斬-字典樹_leetcode 字典樹-CSDN博客

于是開始搜索,搜索時為了避免重復搜索,可以使用記憶化搜索,確保每輪只要搜索一次。

與之前動態轉移從前往后判斷,用?dp?來記錄前綴是否滿足條件不同,這次我們從后往前判斷,并?dp?我們用來記錄后綴是否滿足條件。

搜索分三部分:特判,搜索找到后進行遞歸搜索以及搜索沒找到時的遍歷搜索

第一部分是特判。每次搜索,特判若首字母不在字典樹中則直接返回失敗,若整個字符串在字典樹中被搜到則直接返回成功。

第二部分是遞歸搜索。從頭開始尋找字典樹中的字段位置,若搜索到,則以當前位置進行遞歸向后搜索。

第三部分是遍歷搜索。當然若沒搜索到,則將當前搜索點向后順移一位判斷被延長后的子串是否在字典樹中,并繼續搜索

/*
Author Owen_Q
*/
public class WordBreak {public static boolean wordBreakTrie(String s, List<String> wordDict) {int len = s.length();int[] dp = new int[len];Trie trie = new Trie();for (String word : wordDict) {trie.insert(word);}return wordBreakTrieSearch(s, trie, 0, dp);}private static boolean wordBreakTrieSearch(String s, Trie trie, int pos, int[] dp) {int len = s.length();if (dp[pos] != 0) {return dp[pos] == 1;}if (!trie.startsWith(String.valueOf(s.charAt(pos)))) {dp[pos] = -1;return false;}if (trie.search(s.substring(pos))) {dp[pos] = 1;return true;}for (int i = pos + 1; i < len; i++) {if (trie.search(s.substring(pos, i)) && wordBreakTrieSearch(s, trie, i, dp)) {dp[pos] = 1;return true;}if (!trie.startsWith(s.substring(pos, i + 1))) {dp[pos] = -1;return false;}}dp[pos] = -1;return false;}
}

效果還是挺明顯的

32. Longest Valid Parentheses[Hard]

思路:作為dp專題唯一的hard,倒是要好好來看一下。

括號匹配,求最長合法括號串。

由于合法括號串一定是以?)?結尾,因此所有?(?處的值一定為0。

接下來開始考慮轉移。

一共有兩種轉移方案,剛好對應了括號串的兩種合法狀態

一是...()

若當前位的前一位為?(,則可以直接形成匹配,長度無腦加2

二是...((...))

若當前位的前一位為?),則需要判斷前一位是否形成合法串了。如果形成了合法串,則需要再向前找到前一位合法串前的位是否為?(,即是否可以再前一個合法串外圍再包一個匹配。

此外還需要再注意的一點就是,如果外圍匹配成功,則需要再向前往一位,再加一個前位的合法串長度。因為你多一個匹配很有可能將兩個合法串連接到了一起

/*
Author Owen_Q
*/
public class LongestValidParentheses {public static int longestValidParentheses(String s) {int len = s.length();int[] dp = new int[len + 1];int maxLen = 0;for (int i = 0; i < len; i++) {if (s.charAt(i) == '(') {continue;}if (i > 0 && s.charAt(i - 1) == '(') {dp[i + 1] = dp[i - 1] + 2;maxLen = Math.max(maxLen, dp[i + 1]);} else if (i - dp[i] > 0 && s.charAt(i - dp[i] - 1) == '(') {dp[i + 1] = dp[i] + 2;if (i - dp[i] - 1 > 0) {dp[i + 1] += dp[i - dp[i] - 1];}maxLen = Math.max(maxLen, dp[i + 1]);}}return maxLen;}}

多學一點:貪心

回歸傳統思維,直接貪心模擬。實時記錄當前左右括號的數量,當右括號數量多于左括號時,那么前面的一定無法組成合法場景,直接從頭開始計算。當左右括號數量相等時,統計此時的模擬長度。但這種場景其實針對最終左括號多于右括號的場景無法得出,因為不知道最右邊的右括號匹配到了哪個左括號,即有效的長度究竟是多少。那么最簡單的方式就是反過來再求一次就好了

/*
Author Owen_Q
*/
public class LongestValidParentheses {public static int longestValidParenthesesGreedy(String s) {int sLen = s.length();int left = 0;int right = 0;int len = 0;int maxLen = 0;for (int i = 0; i < sLen; i++) {len++;if (s.charAt(i) == '(') {left++;} else {right++;}if (right > left) {left = 0;right = 0;len = 0;}if (left == right) {maxLen = Math.max(maxLen, len);}}left = 0;right = 0;len = 0;for (int i = sLen - 1; i >= 0; i--) {len++;if (s.charAt(i) == '(') {left++;} else {right++;}if (right < left) {left = 0;right = 0;len = 0;}if (left == right) {maxLen = Math.max(maxLen, len);}}return maxLen;}}

多學一點 :棧

其實針對左括號比右括號多無法定位到具體位置的問題,用棧就可以很好的解決。棧可以實時獲取到當前合法串的長度。我們只要把棧底元素始終放置此輪合法的起點,即左括號不比右括號少的首個位置。然后每次左括號位置進棧,右括號位置出棧。那么此輪出棧的元素一定都是合法串的一部分,于是我們只需要在每次出棧的時候,比較當前位置與棧頂位置的差值,即從棧頂到當前一共有多少個元素在棧外,即可獲取到當前串的長度。最后,針對左括號少于右括號的場景,把棧底元素出棧后,再將當前元素入棧,即可確保起點也被成功更新,開啟新的一輪

/*
Author Owen_Q
*/
public class LongestValidParentheses {public static int longestValidParenthesesStack(String s) {Stack<Integer> stack = new Stack<>();stack.push(-1);int len = s.length();int maxLen = 0;for (int i = 0; i < len; i++) {if (s.charAt(i) == '(') {stack.push(i);} else {stack.pop();if (stack.isEmpty()) {stack.push(i);} else {int top = stack.peek();maxLen = Math.max(maxLen, i - top);}}}return maxLen;}}

完結撒花

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86570.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

策略模式與工廠模式的黃金組合:從設計到實戰

策略模式和工廠模式是軟件開發中最常用的兩種設計模式&#xff0c;當它們結合使用時&#xff0c;能產生11>2的效果。本文將通過實際案例&#xff0c;闡述這兩種模式的協同應用&#xff0c;讓代碼架構更優雅、可維護性更強。 一、為什么需要組合使用&#xff1f; 單獨使用的…

SAP PP模塊與MM模塊作用詳解

SAP PP模塊與MM模塊作用詳解 一、PP模塊&#xff08;Production Planning&#xff09;—— 生產計劃與執行中樞 核心作用&#xff1a;將銷售需求轉化為可執行的生產指令&#xff0c;管控從計劃到完工的全過程。 關鍵功能 功能說明業務價值主數據管理維護BOM&#xff08;物料…

Linux tcp_info:監控TCP連接的秘密武器

深入解析 Linux tcp_info&#xff1a;TCP 狀態的實時監控利器 在開發和運維網絡服務時&#xff0c;我們常常遇到這些問題&#xff1a; 我的 TCP 連接為什么速度慢&#xff1f;是發生了重傳&#xff0c;還是窗口太小&#xff1f;擁塞控制到底有沒有生效&#xff1f; 這些問題…

CVE-2015-5531源碼分析與漏洞復現(Elasticsearch目錄遍歷漏洞)

概述 漏洞名稱&#xff1a;Elasticsearch 快照API目錄遍歷漏洞 CVE 編號&#xff1a;CVE-2015-5531 CVSS 評分&#xff1a;7.5 影響版本&#xff1a; Elasticsearch 1.0.0–1.6.0&#xff08;1.5.1及以前版本無需配置即可觸發&#xff1b;1.5.2–1.6.0需配置path.repo&#xf…

HexHub開發運維利器Database, Docker, SSH, SFTP

支持隧道&#xff0c;SFTP&#xff0c;X11轉發&#xff0c;跳板機&#xff0c;分屏廣播輸入&#xff0c;LRZSZ&#xff0c;TRZSZ&#xff0c;SCP 分屏廣播輸入 管理多臺服務器&#xff0c;更快一步 支持多種文件傳輸協議 支持跨服務器文件傳輸&#xff0c;使用復制粘貼即可進…

2025年教育、心理健康與信息管理國際會議(EMHIM 2025)

2025 2nd International Conference on Education, Mental Health, and Information Management 一、大會信息 會議簡稱&#xff1a;EMHIM 2025 大會地點&#xff1a;中國三亞 收錄檢索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Scholar等 二、會議簡介 第二屆教…

數字孿生技術為UI前端注入新活力:實現智能化交互新體驗

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在數字化轉型的深水區&#xff0c;數字孿生技術正以破竹之勢重構 UI 前端的技術邏輯與交互范式…

組件協作模式

目錄 “組件協作”模式模板方法模式動機模式定義結構要點總結 “組件協作”模式 現代軟件專業分工之后的第一個結果是“框架與應用程序的劃分”。“組件協作”模式通過晚期綁定&#xff0c;實現框架與應用程序之間的松耦合&#xff0c;是二者之間協作時常用的模式。典型模式&a…

Docker 運行RAGFlow 搭建RAG知識庫

借鑒視頻&#xff1a;DeepSeek 10分鐘完全本地部署 保姆級教程 斷網運行 無懼隱私威脅 大語言模型 CPU GPU 混合推理32B輕松本地部署&#xff01;DeepSeek模擬王者&#xff01;&#xff01;_嗶哩嗶哩_bilibili 借鑒博客&#xff1a;RAGFlow搭建全攻略&#xff1a;從入門到精通…

python編寫腳本每月1號和15號執行一次將TRX是否強更發送到釘釘

編寫腳本 import requests import json import time import hmac import hashlib import base64 import urllib.parse# 1. 配置釘釘機器人 webhook "https://oapi.dingtalk.com/robot/send?access_tokenXXXXXX" secret "XXXXXXXX" # 如果沒有加簽驗…

Linux-系統管理

[rootlocalhost ~]# lscpu //查看cpu [rootlocalhost etc]# cat /etc/redhat-release //查看當前目錄的版本信息 [rootlocalhost ~]# ifconfig //查看當前激活的網卡信息 [rootlocalhost ~]# ifconfig ens33 192.168.1.10 //給網卡配置臨時地址 [rootlocalhost ~]# hostnam…

【Spring】系統化的 Spring Boot 全棧學習教程,涵蓋基礎配置、核心功能、進階實戰及文檔自動生成

這里寫目錄標題 &#x1f6e0;? **一、環境搭建與項目創建**1. 開發環境準備2. 創建第一個項目&#xff08;Spring Initializr&#xff09; &#x1f680; **二、核心功能開發**1. RESTful API 開發2. 數據持久化&#xff08;Spring Data JPA&#xff09;3. 配置文件多環境切換…

Discrete Audio Tokens: More Than a Survey

文章目錄 模型設計的考慮量化的方式&#xff1a;比特率&#xff1a;Fixed vs. Adaptive Bitrate碼本內容設計的考慮Streamability. 模型評估Reconstruction Evaluation and Complexity Analysis.識別和生成任務&#xff08;SE, SR)Acoustic Language Modeling.Music Generation…

設計在線教育項目核心數據庫表

1 在線教育項目核心數據庫表設計-ER圖 簡介&#xff1a;設計在線教育的核心庫表結構 在線教育站點速覽 xdclass.net ER圖知識回顧&#xff1a; 實體對象&#xff1a;矩形屬性&#xff1a;橢圓關系&#xff1a;菱形 核心庫表 videochapterepisodeuservideo_ordervideo_banner…

【音視頻】Ubuntu下配置ffmpeg庫

一、下載預編譯的庫 在github上可以找到編譯好的ffmpeg&#xff0c;多個版本的都有&#xff0c;這里我下載ffmpeg編譯好的動態庫 倉庫鏈接&#xff1a;(https://github.com/BtbN/FFmpeg-Builds/releases 下載后解壓得到 二、配置環境變量 打開.bashrc配置文件&#xff0c;添…

equine在神經網絡中建立量化不確定性

?一、軟件介紹 文末提供程序和源碼下載 眾所周知&#xff0c;用于監督標記問題的深度神經網絡 &#xff08;DNN&#xff09; 可以在各種學習任務中產生準確的結果。但是&#xff0c;當準確性是唯一目標時&#xff0c;DNN 經常會做出過于自信的預測&#xff0c;并且無論測試數…

C++動態鏈接庫之非托管封裝Invoke,供C#/C++ 等編程語言使用,小白教程——C++動態鏈接庫(一)

目錄&#xff1a; 一、前言及背景1.1需求描述1.2應用背景 二、編程基礎知識2.1非托管方式交互邏輯2.2該方式下C 與C# 數據轉換對應2.3VS工程下的注意點2.4C封裝接口2.4.1 __declspec(dllexport) 方式2.4.2 .def 文件方式2.4.3結合使用&#xff08;高級&#xff09; 2.5C# 封裝接…

消息隊列的網絡模型詳解:IO多路復用、Reactor模型、零拷貝

文章目錄 一、消息隊列的網路模型擬解決問題單個請求性能優化1. 編解碼速度2. 網絡模塊處理速度 并發請求性能優化1. 高效的連接管理2. 快速處理高并發請求3. 大流量場景處理 二、一些技術基礎知識1. 基于多路復用技術管理 TCP 連接&#xff08;提高性能&#xff09;&#xff0…

【生成模型】【模型介紹】(一)視頻生成Wan2.1速度質量簡單評測

基礎模型&#xff1a;FramePack https://github.com/kijai/ComfyUI-FramePackWrapper huggingface-cli download Comfy-Org/HunyuanVideo_repackaged --local-dir Comfy-Org/HunyuanVideo_repackaged --resume-download huggingface-cli download Comfy-Org/sigclip_vision_3…

微信小程序之滑塊scroll-view

我們要做的東西&#xff1a; 滑塊的視頻 我們先做個基本的圖片和文字(wxm;)&#xff1a; <scroll-view><view class"scrollItem"><image src"https://bkimg.cdn.bcebos.com/pic/fc1f4134970a304e251fd88e8191b086c9177f3ef634?x-bce-processim…