LeetCode BFS解決最短路問題

廣度優先搜索(BFS, Breadth-First Search)是一種用于圖和樹結構的遍歷算法,特別適合解決無權圖的最短路徑問題

算法思想

BFS從起始節點開始,按照"廣度優先"的原則,逐層向外擴展搜索:

  1. 先訪問起始節點的所有相鄰節點(第一層)。
  2. 然后訪問這些相鄰節點的相鄰節點(第二層)。
  3. 依此類推,直到找到目標節點或遍歷完整個圖。

BFS最短路徑算法步驟

  1. 初始化
    • 創建隊列,放入起始節點。
    • 記錄每個節點的訪問狀態和距離(起始節點距離為0)。
  2. 循環處理隊列
    • 取出隊首節點。
    • 遍歷其所有未訪問的鄰居節點。
    • 記錄這些鄰居的距離(當前節點距離+1)。
    • 將鄰居節點加入隊列。
  3. 終止條件
    • 找到目標節點時返回其距離。
    • 隊列為空時表示無法到達。

中等

433. 最小基因變化

基因序列可以表示為一條由 8 個字符組成的字符串,其中每個字符都是 'A''C''G''T' 之一。

假設我們需要調查從基因序列 start 變為 end 所發生的基因變化。一次基因變化就意味著這個基因序列中的一個字符發生了變化。

  • 例如,"AACCGGTT" --> "AACCGGTA" 就是一次基因變化。

另有一個基因庫 bank 記錄了所有有效的基因變化,只有基因庫中的基因才是有效的基因序列。(變化后的基因必須位于基因庫 bank 中)

給你兩個基因序列 startend ,以及一個基因庫 bank ,請你找出并返回能夠使 start 變化為 end 所需的最少變化次數。如果無法完成此基因變化,返回 -1

注意:起始基因序列 start 默認是有效的,但是它并不一定會出現在基因庫中。

示例 1:

輸入:start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
輸出:1

示例 2:

輸入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
輸出:2

示例 3:

輸入:start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"]
輸出:3

提示:

  • start.length == 8
  • end.length == 8
  • 0 <= bank.length <= 10
  • bank[i].length == 8
  • startendbank[i] 僅由字符 ['A', 'C', 'G', 'T'] 組成
int minMutation(string startGene, string endGene, vector<string>& bank) {if (startGene == endGene) {return 0;}unordered_set<string> vis;unordered_set<string> hash(bank.begin(), bank.end());const string change = "ACGT";queue<string> que;que.push(startGene);hash.insert(startGene);int step = 0;while (!que.empty()) {step++;int n = que.size();while (n--) {string str = que.front();que.pop();for (int i = 0; i < 8; ++i) {string tmp = str;for (int j = 0; j < 4; ++j) {tmp[i] = change[j];if (hash.count(tmp) && !vis.count(tmp)) {if (tmp == endGene) {return step;}vis.insert(tmp);que.push(tmp);}}}}}return -1;
}

542. 01 矩陣

給定一個由 01 組成的矩陣 mat ,請輸出一個大小相同的矩陣,其中每一個格子是 mat 中對應位置元素到最近的 0 的距離。

兩個相鄰元素間的距離為 1

示例 1:

img
輸入:mat = [[0,0,0],[0,1,0],[0,0,0]]
輸出:[[0,0,0],[0,1,0],[0,0,0]]

示例 2:

img
輸入:mat = [[0,0,0],[0,1,0],[1,1,1]]
輸出:[[0,0,0],[0,1,0],[1,2,1]]

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 104
  • 1 <= m * n <= 104
  • mat[i][j] is either 0 or 1.
  • mat 中至少有一個 0
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {// 正難則反// 把0當作起點,1當作終點int m = mat.size(), n = mat[0].size();vector<vector<bool>> vis(m, vector<bool>(n, false));queue<pair<int, int>> que;for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (mat[i][j] == 0) {que.emplace(i, j);vis[i][j] = true;}}}vector<vector<int>> ans(mat);int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny]) {vis[nx][ny] = true;ans[nx][ny] = step;que.emplace(nx, ny);}}}}return ans;
}

優化

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {// 正難則反// 把0當作起點,1當作終點int m = mat.size(), n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> que;for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (mat[i][j] == 0) {que.emplace(i, j);dist[i][j] = 0;}}}while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && dist[nx][ny] == -1) {dist[nx][ny] = dist[x][y] + 1;que.emplace(nx, ny);}}}return dist;
}

1162. 地圖分析

你現在手里有一份大小為 n x n 的 網格 grid,上面的每個 單元格 都用 01 標記好了。其中 0 代表海洋,1 代表陸地。

請你找出一個海洋單元格,這個海洋單元格到離它最近的陸地單元格的距離是最大的,并返回該距離。如果網格上只有陸地或者海洋,請返回 -1

我們這里說的距離是「曼哈頓距離」( Manhattan Distance):(x0, y0)(x1, y1) 這兩個單元格之間的距離是 |x0 - x1| + |y0 - y1|

示例 1:

img

輸入:grid = [[1,0,1],[0,0,0],[1,0,1]]
輸出:2
解釋: 
海洋單元格 (1, 1) 和所有陸地單元格之間的距離都達到最大,最大距離為 2。

示例 2:

img

輸入:grid = [[1,0,0],[0,0,0],[0,0,0]]
輸出:4
解釋: 
海洋單元格 (2, 2) 和所有陸地單元格之間的距離都達到最大,最大距離為 4。

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 100
  • grid[i][j] 不是 0 就是 1
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {1, -1, 0, 0};int maxDistance(vector<vector<int>>& grid) {queue<pair<int, int>> que;int m = grid.size(), n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (grid[i][j] == 1) {que.emplace(i, j);dist[i][j] = 0;}}}int ans = -1;while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && dist[nx][ny] == -1) {dist[nx][ny] = dist[x][y] + 1;ans = max(ans, dist[nx][ny]);que.emplace(nx, ny);}}}return ans;
}

1765. 地圖中的最高點

給你一個大小為 m x n 的整數矩陣 isWater ,它代表了一個由 陸地水域 單元格組成的地圖。

  • 如果 isWater[i][j] == 0 ,格子 (i, j) 是一個 陸地 格子。
  • 如果 isWater[i][j] == 1 ,格子 (i, j) 是一個 水域 格子。

你需要按照如下規則給每個單元格安排高度:

  • 每個格子的高度都必須是非負的。
  • 如果一個格子是 水域 ,那么它的高度必須為 0
  • 任意相鄰的格子高度差 至多1 。當兩個格子在正東、南、西、北方向上相互緊挨著,就稱它們為相鄰的格子。(也就是說它們有一條公共邊)

找到一種安排高度的方案,使得矩陣中的最高高度值 最大

請你返回一個大小為 m x n 的整數矩陣 height ,其中 height[i][j] 是格子 (i, j) 的高度。如果有多種解法,請返回 任意一個

示例 1:

img

輸入:isWater = [[0,1],[0,0]]
輸出:[[1,0],[2,1]]
解釋:上圖展示了給各個格子安排的高度。
藍色格子是水域格,綠色格子是陸地格。

示例 2:

img

輸入:isWater = [[0,0,1],[1,0,0],[0,0,0]]
輸出:[[1,1,0],[0,1,1],[1,2,2]]
解釋:所有安排方案中,最高可行高度為 2 。
任意安排方案中,只要最高高度為 2 且符合上述規則的,都為可行方案。

提示:

  • m == isWater.length
  • n == isWater[i].length
  • 1 <= m, n <= 1000
  • isWater[i][j] 要么是 0 ,要么是 1
  • 至少有 1 個水域格子。

**注意:**本題與 542 題相同。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {queue<pair<int, int>> que;int m = isWater.size(), n = isWater[0].size();vector<vector<int>> ans(m, vector<int>(n, -1));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (isWater[i][j] == 1) {que.emplace(i, j);ans[i][j] = 0;}}}while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && ans[nx][ny] == -1) {ans[nx][ny] = ans[x][y] + 1;que.emplace(nx, ny);}}}return ans;
}

1926. 迷宮中離入口最近的出口

給你一個 m x n 的迷宮矩陣 maze下標從 0 開始),矩陣中有空格子(用 '.' 表示)和墻(用 '+' 表示)。同時給你迷宮的入口 entrance ,用 entrance = [entrancerow, entrancecol] 表示你一開始所在格子的行和列。

每一步操作,你可以往 或者 移動一個格子。你不能進入墻所在的格子,你也不能離開迷宮。你的目標是找到離 entrance 最近 的出口。出口 的含義是 maze 邊界 上的 空格子entrance 格子 不算 出口。

請你返回從 entrance 到最近出口的最短路徑的 步數 ,如果不存在這樣的路徑,請你返回 -1

示例 1:

img
輸入:maze = [["+","+",".","+"],[".",".",".","+"],["+","+","+","."]], entrance = [1,2]
輸出:1
解釋:總共有 3 個出口,分別位于 (1,0),(0,2) 和 (2,3) 。
一開始,你在入口格子 (1,2) 處。
- 你可以往左移動 2 步到達 (1,0) 。
- 你可以往上移動 1 步到達 (0,2) 。
從入口處沒法到達 (2,3) 。
所以,最近的出口是 (0,2) ,距離為 1 步。

示例 2:

img
輸入:maze = [["+","+","+"],[".",".","."],["+","+","+"]], entrance = [1,0]
輸出:2
解釋:迷宮中只有 1 個出口,在 (1,2) 處。
(1,0) 不算出口,因為它是入口格子。
初始時,你在入口與格子 (1,0) 處。
- 你可以往右移動 2 步到達 (1,2) 處。
所以,最近的出口為 (1,2) ,距離為 2 步。

示例 3:

img
輸入:maze = [[".","+"]], entrance = [0,0]
輸出:-1
解釋:這個迷宮中沒有出口。

提示:

  • maze.length == m
  • maze[i].length == n
  • 1 <= m, n <= 100
  • maze[i][j] 要么是 '.' ,要么是 '+'
  • entrance.length == 2
  • 0 <= entrancerow < m
  • 0 <= entrancecol < n
  • entrance 一定是空格子。

BFS層序遍歷,每次step++,第一次到達邊界時就是最短路徑,vis數組判斷是否訪問過該節點。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {int m = maze.size(), n = maze[0].size();vector<vector<bool>> vis(m, vector<bool>(n, false));queue<pair<int, int>> que;que.emplace(entrance[0], entrance[1]);vis[entrance[0]][entrance[1]] = true;int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny]) {vis[nx][ny] = true;if (maze[nx][ny] == '.') {if (nx == 0 || nx == m - 1 || ny == 0 || ny == n - 1) {return step;}que.emplace(nx, ny);}}}}}return -1;
}

困難

127. 單詞接龍

字典 wordList 中從單詞 beginWordendWord轉換序列 是一個按下述規格形成的序列 beginWord -> s1 -> s2 -> ... -> sk

  • 每一對相鄰的單詞只差一個字母。
  • 對于 1 <= i <= k 時,每個 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
  • sk == endWord

給你兩個單詞 beginWordendWord 和一個字典 wordList ,返回 beginWordendWord最短轉換序列 中的 單詞數目 。如果不存在這樣的轉換序列,返回 0

示例 1:

輸入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
輸出:5
解釋:一個最短轉換序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的長度 5。

示例 2:

輸入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
輸出:0
解釋:endWord "cog" 不在字典中,所以無法進行轉換。

提示:

  • 1 <= beginWord.length <= 10
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 5000
  • wordList[i].length == beginWord.length
  • beginWordendWordwordList[i] 由小寫英文字母組成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

和這題類似433. 最小基因變化

int ladderLength(string beginWord, string endWord, vector<string>& wordList) {if (beginWord == endWord) {return 0;}unordered_set<string> vis;unordered_set<string> hash(wordList.begin(), wordList.end());if (!hash.count(endWord)) {return 0;}int step = 1;int n = beginWord.size();queue<string> que;que.push(beginWord);vis.insert(beginWord);while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {string str = que.front();que.pop();for (int i = 0; i < n; ++i) {string tmp = str;for (char ch = 'a'; ch <= 'z'; ++ch) {tmp[i] = ch;if  (hash.count(tmp) && !vis.count(tmp)) {if (tmp == endWord) {return step;}vis.insert(tmp);que.push(tmp);}}}}}return 0;
}

675. 為高爾夫比賽砍樹

你被請來給一個要舉辦高爾夫比賽的樹林砍樹。樹林由一個 m x n 的矩陣表示, 在這個矩陣中:

  • 0 表示障礙,無法觸碰
  • 1 表示地面,可以行走
  • 比 1 大的數 表示有樹的單元格,可以行走,數值表示樹的高度

每一步,你都可以向上、下、左、右四個方向之一移動一個單位,如果你站的地方有一棵樹,那么你可以決定是否要砍倒它。

你需要按照樹的高度從低向高砍掉所有的樹,每砍過一顆樹,該單元格的值變為 1(即變為地面)。

你將從 (0, 0) 點開始工作,返回你砍完所有樹需要走的最小步數。 如果你無法砍完所有的樹,返回 -1

可以保證的是,沒有兩棵樹的高度是相同的,并且你至少需要砍倒一棵樹。

示例 1:

img
輸入:forest = [[1,2,3],[0,0,4],[7,6,5]]
輸出:6
解釋:沿著上面的路徑,你可以用 6 步,按從最矮到最高的順序砍掉這些樹。

示例 2:

img
輸入:forest = [[1,2,3],[0,0,0],[7,6,5]]
輸出:-1
解釋:由于中間一行被障礙阻塞,無法訪問最下面一行中的樹。

示例 3:

輸入:forest = [[2,3,4],[0,0,5],[8,7,6]]
輸出:6
解釋:可以按與示例 1 相同的路徑來砍掉所有的樹。
(0,0) 位置的樹,可以直接砍去,不用算步數。

提示:

  • m == forest.length
  • n == forest[i].length
  • 1 <= m, n <= 50
  • 0 <= forest[i][j] <= 109

每次要砍一棵樹都是一次BFS求最短路。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};int cutOffTree(vector<vector<int>>& forest) {vector<pair<int, int>> trees;int m = forest.size(), n = forest[0].size();for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (forest[i][j] > 1) {trees.emplace_back(i, j);}}}auto cmp = [&](const pair<int, int>& a, const pair<int, int>& b) {return forest[a.first][a.second] < forest[b.first][b.second];};sort(trees.begin(), trees.end(), cmp);int ans = 0;int bx = 0, by = 0;for (auto [ex, ey] : trees) {int step = bfs(forest, bx, by, ex, ey);if (step == -1) {return -1;}ans += step;bx = ex, by = ey;}return ans;
}bool vis[55][55];
int bfs(vector<vector<int>>& forest, int bx, int by, int ex, int ey) { if (bx == ex && by == ey) {return 0;}int m = forest.size(), n = forest[0].size();memset(vis, 0, sizeof(vis));queue<pair<int, int>> que;que.emplace(bx, by);int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && forest[nx][ny] != 0 && vis[nx][ny] == false) {if (nx == ex && ny == ey) {return step;}vis[nx][ny] = true;que.emplace(nx, ny);}}}}return -1;
}

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

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

相關文章

[物聯網iot]對比WIFI、MQTT、TCP、UDP通信協議

第一步&#xff1a;先理解最基礎的關系&#xff08;類比快遞&#xff09; 假設你要給朋友寄快遞&#xff1a; Wi-Fi&#xff1a;相當于“公路和卡車”&#xff0c;負責把包裹從你家運到快遞站。 TCP/UDP&#xff1a;相當于“快遞公司的運輸規則”。 TCP&#xff1a;順豐快遞&…

基于python的電影數據分析及可視化系統

一、項目背景 隨著電影行業的快速發展&#xff0c;電影數據日益豐富&#xff0c;如何有效地分析和可視化這些數據成為行業內的一個重要課題。本系統旨在利用Python編程語言&#xff0c;結合數據分析與可視化技術&#xff0c;為電影行業從業者、研究者及愛好者提供一個便捷的電…

Java8 到 Java21 系列之 Lambda 表達式:函數式編程的開端(Java 8)

Java8 到 Java21 系列之 Lambda 表達式&#xff1a;函數式編程的開端&#xff08;Java 8&#xff09; 系列目錄 Java8 到 Java21 系列之 Lambda 表達式&#xff1a;函數式編程的開端&#xff08;Java 8&#xff09;Java 8 到 Java 21 系列之 Stream API&#xff1a;數據處理的…

②EtherCAT/Ethernet/IP/Profinet/ModbusTCP協議互轉工業串口網關

型號 協議轉換通信網關 EtherCAT 轉 Modbus TCP 配置說明 網線連接電腦到模塊上的 WEB 網頁設置網口&#xff0c;電腦所連網口的網段設置成 192.168.1.X&#xff08;X 是除 8 外的任一數值&#xff09;后&#xff0c;打開瀏覽器&#xff0c;地址欄輸入 192.168.1.8 &#xff…

機器視覺--python基礎語法

Python基礎語法 1. Python標識符 在 Python 里&#xff0c;標識符由字母、數字、下劃線組成。 在 Python 中&#xff0c;所有標識符可以包括英文、數字以及下劃線(_)&#xff0c;但不能以數字開頭。 Python 中的標識符是區分大小寫的。 以下劃線開頭的標識符是有特殊意義的…

算法日常記錄

1. 鏈表 1.1 刪除鏈表的倒數第 N 個結點 問題描述&#xff1a;給你一個鏈表&#xff0c;刪除鏈表的倒數第 n 個結點&#xff0c;并且返回鏈表的頭結點。 輸入&#xff1a;head [1,2,3,4,5], n 2 輸出&#xff1a;[1,2,3,5] 思路&#xff1a;先讓fast跑n步&#xff0c;然后…

14使用按鈕實現helloworld(1)

目錄 還可以通過按鈕的方式來創建 hello world 涉及Qt 中的信號槽機制本質就是給按鈕的點擊操作,關聯上一個處理函數當用戶點擊的時候 就會執行這個處理函數 connect&#xff08;誰發的信號&#xff0c; 信號類型&#xff0c; 誰來處理這個信息&#xff0c; 怎么處理的&…

【Golang】泛型與類型約束

文章目錄 一、環境二、沒有泛型的Go三、泛型的優點四、理解泛型&#xff08;一&#xff09;泛型函數&#xff08;Generic function&#xff09;1&#xff09;定義2&#xff09;調用 &#xff08;二&#xff09;類型約束&#xff08;Type constraint&#xff09;1&#xff09;接…

k8s常用總結

1. Kubernetes 架構概覽 主節點&#xff08;Master&#xff09;&#xff1a; 負責集群管理&#xff0c;包括 API Server、Controller Manager、Scheduler 和 etcd 存儲。 工作節點&#xff08;Node&#xff09;&#xff1a; 運行 Pod 和容器&#xff0c;包含 kubelet、kube-pr…

Android 單例模式全解析:從基礎實現到最佳實踐

單例模式&#xff08;Singleton Pattern&#xff09;是軟件開發中常用的設計模式&#xff0c;其核心是確保一個類在全局范圍內只有一個實例&#xff0c;并提供全局訪問點。在 Android 開發中&#xff0c;單例模式常用于管理全局資源&#xff08;如網絡管理器、數據庫助手、配置…

ffmpeg濾鏡使用

ffmpeg實現畫中畫效果 FFmpeg中&#xff0c;可以通過overlay將多個視頻流、多個多媒體采集設備、多個視頻文件合并到一個界面中&#xff0c;生成畫中畫的效果 FFmpeg 濾鏡 overlay 基本參數 x和y x坐標和Y坐標 eof action 遇到 eof表示時的處理方式&#xff0c;默認為重復。…

OpenAI即將開源!DeepSeek“逼宮”下,AI爭奪戰將走向何方?

OpenAI 終于要 Open 了。 北京時間 4 月 1 日凌晨&#xff0c;OpenAI 正式宣布&#xff1a;將在未來幾個月內開源一款具備推理能力的語言模型&#xff0c;并開放訓練權重參數。這是自 2019 年 GPT-2 部分開源以來&#xff0c;OpenAI 首次向公眾開放核心模型技術。 【圖片來源于…

貪心算法,其優缺點是什么?

什么是貪心算法&#xff1f; 貪心算法(Greedy Algorithm)是一種在每一步選擇中都采取在當前狀態下最優(局部最優)的選擇&#xff0c;從而希望導致全局最優解的算法策略。 它不像動態規劃那樣考慮所有可能的子問題&#xff0c;而是做出局部最優選擇&#xff0c;依賴這些選擇來…

python string 類型字符拼接 +=的缺點,以及取代方法

在Python中&#xff0c;使用進行字符串拼接雖然語法簡單&#xff0c;但在性能和代碼維護方面存在明顯缺陷。以下是詳細分析及替代方案&#xff1a; 一、的缺點 性能低下 內存分配問題&#xff1a;字符串在Python中不可變&#xff0c;每次操作會創建新字符串對象&#xff0c;導…

web前端開發-JS

web前端開發-JS 什么是JavaScript Web標準也稱網頁標準,由一系列的標準組成,大部分由W3C(World Wide Web Consortium,萬維網聯盟)負責制定。三個組成部分: HTML:負責網頁的結構(頁面元素和內容)。CSS:負責網頁的表現(頁面元素的外觀、位置等頁面樣式,如:顏色、大小等)。JavaS…

Turtle綜合案例實戰(繪制復雜圖形、小游戲)

在學習了 Turtle 基本的繪圖技巧后,我們可以通過結合多個概念和技巧,繪制復雜的圖形或實現簡單的小游戲。本章將介紹兩個實戰案例: 繪制復雜圖形:結合前面所學的知識,繪制一個精美的多層次復雜圖案。簡單的游戲:利用 Turtle 實現一個簡單的小游戲——蛇形游戲,這是一個經…

Python設計模式:克隆模式

1. 什么是克隆模式 克隆模式的核心思想是通過復制一個已有的對象&#xff08;原型&#xff09;來創建一個新的對象&#xff08;克隆&#xff09;。這種方式可以避免重復的初始化過程&#xff0c;從而提高效率。克隆模式通常涉及以下幾個方面&#xff1a; 原型對象&#xff1a…

邏輯漏洞之越權訪問總結

什么是越權訪問漏洞&#xff1f; “越權訪問漏洞” 是 “邏輯漏洞” 的一種&#xff0c;是由于網站系統的權限校驗的邏輯不夠嚴謹&#xff0c;沒有對用戶權限進行嚴格的身份鑒別&#xff0c;導致普通權限的用戶做到了其它普通用戶或管理員才能完成的操作&#xff0c;稱之為“越…

超短波通信模擬設備:增強通信能力的關鍵工具

在全球信息化戰爭的背景下&#xff0c;通信系統扮演著至關重要的角色。為確保通信系統的穩定性和抗干擾能力&#xff0c;超短波通信模擬設備應運而生&#xff0c;為軍事訓練和通信干擾任務提供強大的支持。 設備特點及優勢 便攜性&#xff1a;設備體積小、重量輕&#xff0c;…

C++STL——容器-vector(含部分模擬實現,即地層實現原理)(含迭代器失效問題)

目錄 容器——vector 1.構造 模擬實現 2.迭代器 模擬實現&#xff1a; ?編輯 3.容量 模擬實現&#xff1a; 4.元素的訪問 模擬實現 5.元素的增刪查改 迭代器失效問題&#xff1a; 思考問題 【注】&#xff1a;這里的模擬實現所寫的參數以及返回值&#xff0c;都是…