LeetCode 每周算法 6(图论、回溯)
 
图论算法:
 

 
class Solution:  def dfs(self, grid: List[List[str]], r: int, c: int) -> None:  """  深度优先搜索函数,用于遍历并标记与当前位置(r, c)相连的所有陆地(即值为"1"的格子)为已访问(即标记为0)。  :param grid: 二维网格,其中的每个元素都是'0'或'1'。  :param r: 当前遍历到的行索引。  :param c: 当前遍历到的列索引。  """  grid[r][c] = '0'  nr, nc = len(grid), len(grid[0])  for x, y in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:  if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1":  self.dfs(grid, x, y)  def numIslands(self, grid: List[List[str]]) -> int:  """  计算给定网格中的岛屿数量。  :param grid: 二维网格,其中的每个元素都是'0'或'1'。  :return: 网格中的岛屿数量。  """  nr = len(grid)  if nr == 0:  return 0  nc = len(grid[0])  num_islands = 0  for r in range(nr):  for c in range(nc):  if grid[r][c] == "1":  num_islands += 1  self.dfs(grid, r, c)  return num_islands  
 

 
class Solution:  def orangesRotting(self, grid: List[List[int]]) -> int:  R, C = len(grid), len(grid[0])  queue = deque()  for r, row in enumerate(grid):  for c, val in enumerate(row):  if val == 2:  queue.append((r, c, 0))  def neighbors(r, c):  for nr, nc in ((r - 1, c), (r, c - 1), (r + 1, c), (r, c + 1)):  if 0 <= nr < R and 0 <= nc < C:  yield nr, nc  d = 0  while queue:  r, c, d = queue.popleft()  for nr, nc in neighbors(r, c):  if grid[nr][nc] == 1:  grid[nr][nc] = 2  queue.append((nr, nc, d + 1))  if any(1 in row for row in grid):  return -1  return d  
 

 
class Solution:  def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:  edges = collections.defaultdict(list)  indeg = [0] * numCourses  for info in prerequisites:  edges[info[1]].append(info[0])  indeg[info[0]] += 1  q = collections.deque([u for u in range(numCourses) if indeg[u] == 0])  visited = 0  while q:  visited += 1  u = q.popleft()  for v in edges[u]:  indeg[v] -= 1  if indeg[v] == 0:  q.append(v)  return visited == numCourses
 

 
class Trie:  def __init__(self):  self.children = [None] * 26  self.isEnd = False  def searchPrefix(self, prefix: str) -> "Trie":  node = self  for ch in prefix:  ch = ord(ch) - ord("a")  if not node.children[ch]:  return None  node = node.children[ch]  return node  def insert(self, word: str) -> None:  node = self  for ch in word:  ch = ord(ch) - ord("a")  if not node.children[ch]:  node.children[ch] = Trie()  node = node.children[ch]  node.isEnd = True  def search(self, word: str) -> bool:  node = self.searchPrefix(word)  return node is not None and node.isEnd  def startsWith(self, prefix: str) -> bool:  return self.searchPrefix(prefix) is not None
 
图论算法:
 

 
class Solution {  
public:  void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len) {  if (first == len) {  res.emplace_back(output);  return;  }  for (int i = first; i < len; ++i) {  swap(output[i], output[first]);  backtrack(res, output, first + 1, len);  swap(output[i], output[first]);  }  }  vector<vector<int>> permute(vector<int>& nums) {  vector<vector<int>> res; backtrack(res, nums, 0, (int)nums.size());return res; }  
};
 

 
class Solution {  
public:  vector<int> output;  vector<vector<int>> ans;  vector<vector<int>> subsets(vector<int>& nums) {  for (int mask = 0; mask < (1 << nums.size()); ++mask) {  output.clear();  for (int i = 0; i < nums.size(); ++i) {  if (mask & (1 << i)) {  output.push_back(nums[i]);  }  }  ans.push_back(output);  }  return ans;  }  
};
 

 
class Solution {  
public:  vector<string> letterCombinations(string digits) {  if (digits.empty()) { return combinations;  }  string combination; vector<string> combinations; unordered_map<char, string> phoneMap{  {'2', "abc"},  {'3', "def"},  {'4', "ghi"},  {'5', "jkl"},  {'6', "mno"},  {'7', "pqrs"},  {'8', "tuv"},  {'9', "wxyz"}  };  backtrack(combinations, phoneMap, digits, 0, combination);  return combinations; }  void backtrack(vector<string>& combinations, const unordered_map<char, string>& phoneMap, const string& digits, int index, string& combination) {  if (index == digits.length()) { combinations.push_back(combination);  } else {  char digit = digits[index]; const string& letters = phoneMap.at(digit); for (const char& letter: letters) { combination.push_back(letter); backtrack(combinations, phoneMap, digits, index + 1, combination);  combination.pop_back(); }  }  }  
};
 

 
class Solution {  
public:  vector<vector<int>> result;  vector<int> path;  void backtrack(const vector<int>& candidates, int target, int start) {  if (target < 0) return;  if (target == 0) {  result.push_back(path);  return;  }  for (int i = start; i < candidates.size() && target - candidates[i] >= 0; i++) {  path.push_back(candidates[i]);  backtrack(candidates, target - candidates[i], i);  path.pop_back();  }  }  vector<vector<int>> combinationSum(vector<int>& candidates, int target) {  sort(candidates.begin(), candidates.end());  backtrack(candidates, target, 0);  return result;  }  
};
 

 
class Solution {  void backtrack(vector<string>& result, string& current, int left, int right, int n) {  if (current.size() == n * 2) {  result.push_back(current);  return;  }  if (left < n) {  current.push_back('('); backtrack(result, current, left + 1, right, n); current.pop_back(); }  if (right < left) {  current.push_back(')'); backtrack(result, current, left, right + 1, n); current.pop_back(); }  }  public:  vector<string> generateParenthesis(int n) {  vector<string> result; string current; backtrack(result, current, 0, 0, n); return result; }  
};
 

 
class Solution {  
public:  bool exist(vector<vector<char>>& board, string word) {  for (int i = 0; i < board.size(); i++) {  for (int j = 0; j < board[0].size(); j++) {  vector<vector<bool>> visited(board.size(), vector<bool>(board[0].size(), false));  if (dfs(board, visited, word, 0, i, j)) return true; }  }  return false;  }  private:  bool dfs(vector<vector<char>>& board, vector<vector<bool>>& visited, const string& word, int str_index, int i, int j) {  if (str_index == word.size()) return true;  if (i >= board.size() || i < 0 ||  j >= board[0].size() || j < 0 ||  visited[i][j] == true || board[i][j] != word[str_index]) return false;  visited[i][j] = true;  if (dfs(board, visited, word, str_index + 1, i + 1, j) ||  dfs(board, visited, word, str_index + 1, i - 1, j) ||  dfs(board, visited, word, str_index + 1, i, j + 1) ||  dfs(board, visited, word, str_index + 1, i, j - 1)) return true; visited[i][j] = false;  return false;  }  
};
 

 
class Solution {  
private:  vector<vector<int>> dp;  vector<vector<string>> result;  vector<string> answer;  int n;  public:   void dfs(const string& s, int i) {  if (i == n) {  result.push_back(answer);  return;  }  for (int j = i; j < n; ++j) {  if (dp[i][j]) {  answer.push_back(s.substr(i, j - i + 1));  dfs(s, j + 1);  answer.pop_back();  }  }  }  vector<vector<string>> partition(string s) {  n = s.size();  dp.assign(n, vector<int>(n, true));  for (int i = n - 1; i >= 0; --i) {  for (int j = i; j < n; ++j) {  dp[i][j] = (s[i] == s[j] && (j - i <= 1 || dp[i + 1][j - 1]));  }  }  dfs(s, 0);  return result;  }  
};
 

 
class Solution {  
private:  vector<vector<string>> result;  void backtracking(int n, int row, vector<string>& chessboard) {  if (row == n) {  result.push_back(chessboard);  return;  }  for (int col = 0; col < n; col++) {  if (isvalid(row, col, chessboard, n)) {  chessboard[row][col] = 'Q';  backtracking(n, row + 1, chessboard);  chessboard[row][col] = '.';  }  }  }  bool isvalid(int row, int col, vector<string>& chessboard, int n) {  for (int i = 0; i < row; i++) {  if (chessboard[i][col] == 'Q') {  return false;  }  }  for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {  if (chessboard[i][j] == 'Q') {  return false;  }  }  for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {  if (chessboard[i][j] == 'Q') {  return false;  }  }  return true;  }  public:  vector<vector<string>> solveNQueens(int n) {  result.clear();  vector<string> chessboard(n, string(n, '.'));  backtracking(n, 0, chessboard);  return result;  }  
};