主頁 >  其他 > 演算法導論之眼前一亮(持續更新)

演算法導論之眼前一亮(持續更新)

2020-09-29 08:56:48 其他

本篇文章僅記錄在平時刷題程序中,讓人眼前一亮的處理思路,所以本篇文章適合演算法愛好者閱讀及參考,沒有演算法功底的程式猿們,建議不用花費太多的時間在本篇文章

 

1,題目描述:給定一個字串陣列,請根據“相同字符集”進行分組(摘自 LeetCode 49)

      例           :Input: ["eat", "tea", "tan", "ate", "nat", "bat"],

                        Output:[

                            ["ate","eat","tea"],
                            ["nat","tan"],
                            ["bat"]
                        ]

      基礎分析:這類問題的常見處理并不難,只需要將每個字符記錄對應值,內部回圈比較,外部回圈子串陣列即可,時間復雜度 O(K2[子串平均長度] * N * Log(N)2)

      晉級分析:我在基礎之上,將字串的和存了下來,將內部回圈比較的次數降低,時間復雜度可以達到 O(K2 * N * Log(N) * Min(N)[代表字串和相同的次數])

      高級分析:首先引進一組概念:正整數唯一分解定理,每個大于1的自然數,要么本身為質數,要么可以由2個或以上的質數相乘,且組合唯一;上述定理結合問題來看,我們僅需要將字串中的每個字符與質數一一對應,并將字串所有字符對應的質數乘積保存下來,即可確保字串的 hash 唯一,時間復雜度 O(K * N * Log(N))

     Coding    :

 1 func GroupAnagramsOpt(strs []string) [][]string {
 2     var res [][]string
 3     strMap := make(map[int][]string)
 4     prime := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103}
 5 
 6     for _, str := range strs {
 7         sum := 1
 8         for _, char := range str {
 9             sum = prime[char-'a'] * sum
10         }
11         if _, ok := strMap[sum]; !ok {
12             strMap[sum] = []string{str}
13         } else {
14             strMap[sum] = append(strMap[sum], str)
15         }
16     }
17 
18     for _, v := range strMap {
19         res = append(res, v)
20     }
21 
22     return res
23 }

 

 2,題目描述:給定一個 n,代表 n x n 的棋盤,擺放 n 個皇后,使其相互之間無法攻擊(同一橫豎斜僅一個旗子,8個皇后問題),回傳所有的擺放情況(摘自 LeetCode 50)

       例           :Input: 4

                         Output: [
                         [".Q..","...Q","Q...","..Q."],

                         ["..Q.","Q...","...Q",".Q.."]
                         ]

       基礎分析:采用遞回法與回朔法,每次檢查當前位置可否落子,落子后將當前位置所在的橫豎斜 4 個方向全部置位不可落子,最終得出所有可能

       晉級分析:對于 n x n 矩陣,不可落子不需要記錄到具體的點,僅需要記錄(行、列、左斜(i+j)、右斜(i-j+n))即可快速判斷當前行,列、位置可否落子,省去記錄和判斷的時間復雜度

       高級分析:我自己做的時候,發現一直在糾結重復性問題,所以第一版是在將結果放入佇列時,進行重復排查,發現效率較低;再想通過遞回的回傳值,確定當前位置是否可以再次落子,以排除相同可能性,發現每次回溯后都必須處理標記資料;再后來發現每次遞回的行,無需從 0 開始(同行僅有1個旗子),回圈時不需要每次都從(0,0)點開始判斷,節省相同擺法的重復性時間消耗,

       Coding   :

 1 // 51. N-Queens
 2 func SolveNQueens(n int) [][]string {
 3     stepMap := make([][]bool, 3)
 4     qMap := make([][]bool, n)
 5     for i, _ := range stepMap {
 6         stepMap[i] = make([]bool, 2*n)
 7     }
 8     for i, _ := range qMap {
 9         qMap[i] = make([]bool, n)
10     }
11 
12     t := &struct{ a [][]string }{a: make([][]string, 0)}
13     SolveNQueensSub(stepMap, qMap, t, n, 0)
14     return t.a
15 }
16 
17 func SolveNQueensSub(stepMap [][]bool, qMap [][]bool, res *struct{ a [][]string }, n, i int) {
18     // trans to res
19     if i == n {
20         var vs []string
21         for _, row := range qMap {
22             v := make([]byte, n)
23             for i, r := range row {
24                 if r {
25                     v[i] = 'Q'
26                 } else {
27                     v[i] = '.'
28                 }
29             }
30             vs = append(vs, string(v))
31         }
32         res.a = append(res.a, vs)
33         return
34     }
35 
36     for j := 0; j < n; j++ {
37         // col + / + \
38         if !stepMap[0][j] && !stepMap[1][i+j] && !stepMap[2][j-i+n] {
39             qMap[i][j] = true
40             stepMap[0][j] = true
41             stepMap[1][i+j] = true
42             stepMap[2][j-i+n] = true
43             SolveNQueensSub(stepMap, qMap, res, n, i+1)
44             qMap[i][j] = false
45             stepMap[0][j] = false
46             stepMap[1][i+j] = false
47             stepMap[2][j-i+n] = false
48         }
49     }
50 }

 

3,題目描述:給定兩個字串 A,B,我們可以對 A 字串進行 3 種操作,

    “插入一個字符“

    ”替換一個字符“

    ”洗掉一個字符“

    如何在最少的操作次數后,可以使 A 與 B 相等(摘自 LeetCode 72)

     例           : input: “horse“,”ros“

                        output: 3(1,h -> r,"rorse";2,del 'r',"rose";3,del 'e',"ros")

    基礎分析:暴力法進行遞回回圈,每次成功后,記錄次數回傳最小次數,理論上是 n^3(這種方法我沒有嘗試,一般 leetcode 上的題目超過 n^2 的解法,往往都會超時,這里只是提出一種解法)

    晉級分析:一般看到“最少”/"最大"/“最小”... 這類字眼,我們首先腦子中要冒出 4 個字“動態規劃“,這是一個演算法工程師的基本素質,這道題,我們如果用動態規劃的思路去考慮,就會一目了然,"horse" 和 "ros" 的匹配,我們可以根據動態規劃的思路去進行降級,分別求 "horse" 和 "ro"、"hors" 和 “ros”、    “hors” 和 “ro” 這三種情況下最小次數,這里我們將這三種情況分別稱為 A、B、C 下的最小次數,則最終的最小次數與三種情況的結果息息相關,具體的關系靜下心來推導:

    A 情況:當前最小次數 + 1

    B 情況:當前最小次數 + 1

    C 情況:如果最后一位 'e' 和 's' 相等(這里只是提出假設),則回傳當前最小次數,如果最后一位不相等,則回傳當前最小次數 + 1

    而我們需要的最小次數便是上面 3 種情況最小值,這里就可以給出公式

  if str1[n] == str2[m]  ->  map[n][m] = min(map[n-1][m] + 1,map[n][m-1] + 1, map[n][m])

  else                          ->  map[n][m] = min(map[n-1][m] + 1,map[n][m-1] + 1, map[n][m] + 1)

    當時做題時,根據這樣的邏輯進行編碼后,發現在跑測驗用例時會計算少,為什么呢?其實能看到原因是第一列、第一行是有些特殊的,首先是沒有 m-1、n-1 去比較計算,是能根據前一位判斷當前的最小次數,這一行的邏輯是比較簡單的,簡單就是 "m" 和 "djfioncvohghmnhs" 的匹配,這里不詳細給出推導,有些演算法功底的同學應該是可以很快寫出代碼的,直接上代碼

 1 func MinDistanceV2(word1 string, word2 string) int {
 2     if len(word1) == 0 {
 3         return len(word2)
 4     }
 5     if len(word2) == 0 {
 6         return len(word1)
 7     }
 8 
 9     n := len(word1)
10     m := len(word2)
11     disMap := make([][]int, n)
12     for i := 0; i < n; i++ {
13         disMap[i] = make([]int, m)
14     }
15 
16     // first column
17     isUse := false
18     for i := 0; i < n; i++ {
19         disMap[i][0] = i + 1
20         if word1[i] == word2[0] {
21             isUse = true
22         }
23         if isUse {
24             disMap[i][0]--
25         }
26     }
27 
28     // first row
29     isUse = false
30     for i := 0; i < m; i++ {
31         disMap[0][i] = i + 1
32         if word1[0] == word2[i] {
33             isUse = true
34         }
35         if isUse {
36             disMap[0][i]--
37         }
38     }
39 
40     for i := 1; i < n; i++ {
41         for j := 1; j < m; j++ {
42             dis := Common.MAXINTNUM
43             if word1[i] == word2[j] {
44                 if dis > disMap[i-1][j-1] {
45                     dis = disMap[i-1][j-1]
46                 }
47             } else {
48                 if dis > disMap[i-1][j-1]+1 {
49                     dis = disMap[i-1][j-1] + 1
50                 }
51             }
52             if dis > disMap[i-1][j]+1 {
53                 dis = disMap[i-1][j] + 1
54             }
55             if dis > disMap[i][j-1]+1 {
56                 dis = disMap[i][j-1] + 1
57             }
58             disMap[i][j] = dis
59         }
60     }
61     return disMap[n-1][m-1]
62 }

 

       高級分析:有些人給出一些比較有趣的解法,相較于上述的解法并沒有太多的優化,但多了一份巧妙,可以看到下圖,既然第一行、第一列需要特殊處理,那可以在每個字串前面加一列不存在的字符,初始化是使用 for 回圈對第一行、第一列先進行簡單賦值后再進行公式計算,(這里就不給出代碼了,我個人使用的是第二種方法,之所以將這種方法列為高級分析,僅僅是解題思路需要適當的巧妙,可以讓代碼邏輯看起來簡單很多)

 

 

4,題目描述:給定一個排序陣列和一個目標值,找出陣列中是否含有當前目標(摘自 LeetCode 81)

     例           : input: [1,3,6,7,9];3

                        output: true

    基礎分析:根據原題,當時笨方法 for 回圈,另一種業務中常用的方法便是二分查找法

    晉級分析:之前參加過一個國內知名公司的面試,該公司比較注重演算法,幾乎每場面試都有一個演算法題等著你,而我這次碰到的便是這道題的迭代,在原題的基礎上將陣列進行一次翻滾,將后面一部分(有可能是0-n)按順序挪到陣列前,在這種條件下,我也是沒有任何慫,萬物都有解決的辦法嘛,大不了就是笨方法,但面試官肯定不會對這種笨方法有任何欣賞的點,肯定是需要二分查找法,最終也是利用1-3分鐘將思路和代碼寫了出來,

    很多人其實這里糾結的是每次選前半段還是后半段,其實我們進行拆分,就可以很明確的知道選擇哪邊;

    1,判斷當前中心是在翻滾點的左邊還是右邊,其實就是判斷中間點的指是否大于最后一個值,大于則代表在翻滾點左側,小于則代表在翻滾點右測(這第一步往往很重要,但經常有人考慮不到,包括我自己第一次的思路,因為兩種不同的結果決定下面我們判斷的方式)

    2,當中點在翻滾點左側時,我們只需要比較當前目標是否比首個數字大,如果大,則代表需要查前半段,否則就是后半段;相反,當中點在翻滾點右側時,我們只需要比較當前目標是否比最后一個數字小,如果小,則代表需要查后半段,否則就是前半段

    按上述兩點進行回圈,即可以 O(logn) 的時間復雜度得到結果

    高級分析:當我看似艱難的將上面的代碼寫好之后(其實想的腦闊疼,改了好幾版),還未囂張,面試官突然問如果陣列中有重復的數字時,是否需要做什么修改,我考慮了幾秒,覺得是沒問題,面試官一笑就過了,我以為我的聰明征服了面試官大大,面試結束后興起稍微寫了一下代碼在本地跑完之后,才發現有了重復測驗案例后,結果是錯誤的,冥思苦想覺得例外丟人,并且想了好久的解決方法,其實很簡單,在上面的解法之前做一次判斷

    1,當前中點是否與首位陣列相等,相等則回圈拋棄首位陣列,start++;反之則是 end--;我們直接丟棄掉就可以啦,只是這種方案最壞時間復雜度就降到了 O(n),上最終版代碼

 1 func Search(nums []int, target int) bool {
 2     if len(nums) == 0 {
 3         return false
 4     }
 5 
 6     start := 0
 7     end := len(nums) - 1
 8     for start <= end {
 9         mid := (end-start)/2 + start
10         if nums[mid] == target {
11             return true
12         }
13 
14         for start != mid && nums[mid] == nums[start] {
15             start++
16             if start == mid {
17                 start = mid + 1
18                 goto OUT
19             }
20         }
21         for end != mid && nums[mid] == nums[end] {
22             end--
23             if end == mid {
24                 end = mid - 1
25                 goto OUT
26             }
27         }
28 
29         if nums[mid] < nums[end] {
30             if target > nums[mid] {
31                 if target == nums[end] {
32                     return true
33                 } else if target < nums[end] {
34                     start = mid + 1
35                     end--
36                 } else {
37                     end = mid - 1
38                 }
39             } else {
40                 end = mid - 1
41             }
42 
43         } else {
44             if target < nums[mid] {
45                 if target == nums[start] {
46                     return true
47                 } else if target > nums[start] {
48                     start++
49                     end = mid - 1
50                 } else {
51                     start = mid + 1
52                 }
53             } else {
54                 start = mid + 1
55             }
56         }
57     OUT:
58     }
59     return false
60 }

 

5,題目描述:給定一個陣列,每個數字代表當前位置的柱子高度,請回傳柱子組成所能組成的最大高度(摘自 LeetCode 84)

     例           : input: [3,1,5,4,1]

                        output: 選擇 5,4 -> 4 * 2 = 8

    基礎分析:暴力美學,有用的就是好的方法,對任意兩個位置遍歷并每次計算兩者之間的最低柱子,進行面積計算得出最大的面積,時間復雜度O(n3),按 leetcode 的尿性,這種復雜度是別想跑過測驗用例的

    晉級分析:上述的演算法中,其實我們可以使用 n 的空間,來記錄以當前為起點,后面柱子的最低高度,這樣我們每次就可以省去找出兩點之間高度的次數,時間復雜度O(n2),其實這種方法已經達到了一般演算法喜好者的水準,可作為一名刷題者,這種方法只能讓你通過面試,絕對達不到驚艷的地步,給出代碼:

 1 func LargestRectangleArea(heights []int) int {
 2     if len(heights) == 0 {
 3         return 0
 4     }
 5 
 6     highs := make([]int, 0, len(heights))
 7     res := 0
 8     for i := 0; i < len(heights); i++ {
 9         for j := 0; j < len(highs); j++ {
10             if highs[j] > heights[i] {
11                 highs[j] = heights[i]
12             }
13             curArx := highs[j] * (i - j + 1)
14             if curArx > res {
15                 res = curArx
16             }
17         }
18         if heights[i] > res {
19             res = heights[i]
20         }
21         highs = append(highs, heights[i])
22     }
23     return res
24 }

 

    高級分析:其實可以看到,上述的難點在于我們無法動態的滑動前后兩端,保證每次滑動都為最優解,如果能夠解決這個問題,我們就可以在 O(n)的時間下完成演算法,其實換個角度想,向后滑動時,新的柱子高度如果大于等于上一個柱子,那盡管往上加,面積一定是大的;而如果下一個柱子比當前柱子小,則需要將前面所有的高柱子進行一次計算,得到這一部分的最大面積后,高的那些柱子已經失去意義了(可以將這一段比作一個區間,A-B 之間存在一些高柱子,A 比 B 小,那 A 前列的柱子和 B 后續的柱子無論如何都不可能再用到中間的高柱子,前列的直接按 A 的高度算,后續的直接按 B 的高度算)

 

    由前往后,又要由后往前計算并排除,直接使用堆疊工具,可以給出步驟:

    1,對陣列進行回圈處理,回圈 1,2,3 步,直到所有陣列處理完畢

    1,當前位置高度大于等于堆疊頂的數值時,直接 Push 到堆疊里面

    2,當前位置高度小于堆疊頂數值時,進行 3 步驟回圈,當堆疊為慷訓者堆疊頂數值小于當前位置高度,跳出回圈

    3,取出堆疊頂的數值,進行面積計算,公式:當前高度(h) * 兩點距離

    4,堆疊不為空時,說明還有需要處理的資料,這時候回圈 5 步,直到堆疊為空

    5,取出堆疊頂的陣列,進行面積計算,公式:堆疊頂高度(h)* (陣列長度 - 堆疊頂下標)

    備注:堆疊中存盤(下標,高度),防止最后一個資料未處理,可以提前插入一個 (-1,0) 的資料,當然也可以利用一些邏輯判斷特殊處理

    給出代碼:

 

 1 func LargestRectangleAreaOpt(heights []int) int {
 2     if len(heights) == 0 {
 3         return 0
 4     }
 5     stack := &Common.Stack{}
 6     res := 0
 7 
 8     type node struct {
 9         index int
10         num   int
11     }
12     stack.Push(&node{index: -1, num: 0})
13     for i := 0; i < len(heights); i++ {
14         for stack.Size() > 1 {
15             top := stack.Top().(*node)
16             if heights[i] >= top.num {
17                 break
18             }
19 
20             stack.Pop()
21             nextTop := stack.Top().(*node)
22             area := top.num * (i - nextTop.index - 1)
23             if area > res {
24                 res = area
25             }
26         }
27         stack.Push(&node{index: i, num: heights[i]})
28     }
29 
30     for stack.Size() > 1 {
31         top := stack.Pop().(*node)
32         nextTop := stack.Top().(*node)
33         area := top.num * (len(heights) - 1 - nextTop.index)
34         if area > res {
35             res = area
36         }
37     }
38     return res
39 }

 

 

6,題目描述:給定一個二維陣列,每個位置給定 0 或 1,回傳所能組成最大面積的矩陣(摘自 LeetCode 85)

     例           : input: [1,0,1,1,0],[1,1,1,1,0]

                        output: 選擇 2 * 2 或 1 * 4 = 4

    基礎分析:暴力解法,每個兩個點之間進行判斷,每次遍歷兩點所組成的矩形是否全部為 1,時間復雜度 O(n2m2)不用想了,除非不考慮性能才會這樣做

    晉級分析:動態規劃,在對二維資料的回圈程序中,分別記錄其向上,向左的連續數量,判斷公式:

    if data[i][j] == 1 {left[i] = left[i-1]+1; right[j] = right[j-1] + 1} else {left[i] = 0; right[i] = 0},

    這里可以將每個點的向左向右連續統計出來,而對于當前點的最大面積只需要對一個方向進行遍歷求解即可,簡單給出一張圖

    一個點從下往上回圈計算,便可以的到當前點的最大面積,最終時間復雜度 O(n2m)

    高級分析:動態規劃,很厲害的一種演算法,完全是沒有想到的,這里給出別人的思路,每個點的面積(這里其實并不是最大面積),為當前點的最高高度,按最高高度擴展其寬度,算面積,如圖

 

    可以看到,黃點的面積可以如圖所示計算,開始的時候我很糾結,這樣并不是黃點的最大面積,但我忽略一個重要的問題

 

    按新的面積計算方案,黃點的左右兩側總能找到最大的面積點,所以根據這個思路走下去,利用動態規劃計算新的面積,每個點分別計算當前點的最高高度、高度對應的左側范圍,高度對應的右側范圍,公式分別為

    if data[i][j] == 1 {height[i] = height[i]-1} else {height = 0}

    if data[i][j] == 1 {left[i] = min(left[i-1], continue(左側連續為1的數量)} else {left[i] = 0}

    if data[i][j] == 1 {right[i] = min(right[i-1], continue(右側連續為1的數量)} else {right[i] = 0}

    給出代碼:

 1 func MaximalRectangle(matrix [][]byte) int {
 2     if len(matrix) == 0 || len(matrix[0]) == 0 {
 3         return 0
 4     }
 5 
 6     type node struct {
 7         height int
 8         left   int
 9         right  int
10     }
11     res := 0
12     n := len(matrix)
13     m := len(matrix[0])
14     nodeMat := make([][]node, n)
15     for i := 0; i < n; i++ {
16         nodeMat[i] = make([]node, m)
17     }
18 
19     continueNum := 0
20     // full height and left
21     for i := 0; i < n; i++ {
22         for j := 0; j < m; j++ {
23             if matrix[i][j] == '1' {
24                 continueNum++
25                 if i == 0 {
26                     nodeMat[i][j].height = 1
27                 } else {
28                     nodeMat[i][j].height = 1 + nodeMat[i-1][j].height
29                 }
30 
31                 if j == 0 {
32                     nodeMat[i][j].left = 1
33                 } else {
34                     nodeMat[i][j].left = continueNum
35                     if i != 0 && nodeMat[i-1][j].left != 0 && (nodeMat[i-1][j].left < nodeMat[i][j].left) {
36                         nodeMat[i][j].left = nodeMat[i-1][j].left
37                     }
38                 }
39             } else {
40                 continueNum = 0
41             }
42         }
43         continueNum = 0
44     }
45 
46     // full right
47     for i := 0; i < n; i++ {
48         for j := m - 1; j >= 0; j-- {
49             if matrix[i][j] == '1' {
50                 continueNum++
51                 if j == m-1 {
52                     nodeMat[i][j].right = 1
53                 } else {
54                     nodeMat[i][j].right = continueNum
55                     if i != 0 && nodeMat[i-1][j].right != 0 && (nodeMat[i-1][j].right < nodeMat[i][j].right) {
56                         nodeMat[i][j].right = nodeMat[i-1][j].right
57                     }
58                 }
59                 curArx := nodeMat[i][j].height * (nodeMat[i][j].right + nodeMat[i][j].left - 1)
60                 if curArx > res {
61                     res = curArx
62                 }
63             } else {
64                 continueNum = 0
65             }
66         }
67         continueNum = 0
68     }
69 
70     return res
71 }

 

 

7,題目描述:給定一個陣列,所有元素僅一個出現一次的值,其余均出現三次(摘自 LeetCode 137)

  例     :input: 2,2,1,2

      :out: 1

  基礎分析:暴力解法,遍歷整個陣列元素,使用一個 hash-map 存盤所有的 key-num 值,當出現3次后移除指定的 key,最后僅留的一個 key 回傳即可,時間復雜度為 O(N * 1),這里既是理論值 1,實際應用中 hash 解沖突、hash 定位均需要花費 O(1) 以上的時間,

       晉級分析:位運算,其實位運算除了用來做運算子之外,還有需要其他的用途,比如模擬乘法、判斷數值是否為2的冪次方、判斷一個數的二進制有多少位是1...諸如此類,有興趣的可以到 https://www.zhihu.com/question/38206659 了解一下,

       其實說到位運算可能有些了解的同學已經有反應過來,那就是當其余元素均出現兩次的情況,我們就可以通過^(按位異或)的運算子,遍歷整個陣列,即可消除所有相同的元素,最后僅保留一個僅出現元素;那回來再看,我們如何利用運算子去抵消出現三次的元素呢;我們可以通過多個運算子,模擬出三進制的情形(實際計算機中既不存在三進制、更不存在三進制的位運算,我們只是想辦法去模擬 出現三次抵消掉 而已)

       1,使用變數 a 記錄個位的數值(二進制的 1),使用變數 b 記錄復位的數值(二進制的 2)

       2,當遍歷數值某一個位為 1 時,分別判斷 3,4

  3,當變數 b 的當前位為 1,則說明已經當前位已經出現過 2 次,則本次直接抵消,即 b 和 a 的當前位均置 0

  4,否則當變數 a 的當前位為 0,則改變變數 a 的當前位為 1,

       5,否則即變數 a 的當前位為 1,則修改變數 a 的當前位為 0,修改變數 b 的當前位為 1

       6,遍歷結束后,回傳 a 即可

  上述邏輯看似復雜,但實際代碼中,無需對每位進行判斷,只需使用位運算代理上述邏輯,給出代碼:

 1 func SingleNumberV2Opt(nums []int) int {
 2     a := 0
 3     b := 0
 4 
 5     for _, num := range nums {
 6         tmp := a & num // 得到需要進位的位數字
 7         a = a ^ num    // 計算當前 a 的最終值
 8         b = b ^ tmp    // 計算當前 b 的最終值
 9 
10         tmp = a & b    // 得到 a 和 b 均為 1 的位
11         a = a - tmp    // 消除出現三次的位
12         b = b - tmp    // 消除出現三次的位
13     }
14 
15     return a
16 }

 

 

 

 

用心寫代碼,Refuse copy on coding,Refuse coding by butt.

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/137725.html

標籤:其他

上一篇:獲取陣列中所有重復的元素

下一篇:【題解】游戲

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more