【算法】【搜索和回溯】Leetcode高频面试题
BFS
完全平方数
题目链接:https://leetcode-cn.com/problems/perfect-squares/
class Solution {
public:
int numSquares(int n) {
int max_sqrt = floor(sqrt(n));
queue<int> q;
q.push(0);
int res = 0;
while(!q.empty())
{
int len = q.size();
res++;
for(int i = 0; i < len; i++)
{
int val = q.front();
q.pop();
for(int j = max_sqrt; j >= 0 ; j--)
{
int sum = val + j * j;
if(sum == n) return res;
if(sum > n) continue;
q.push(sum);
}
}
}
return -1;
}
};
岛屿数量
题目链接:https://leetcode-cn.com/problems/number-of-islands/
class Solution {
public:
int res = 0;
int numIslands(vector<vector<char>>& grid) {
if(grid.empty()) return 0;
int n = grid.size(), m = grid[0].size();
vector<vector<bool>> flag(n, vector<bool>(m, false));
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(!flag[i][j] && grid[i][j] == '1')
{
bfs(grid, flag, i, j);
res++;
}
}
}
return res;
}
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& flag, int i, int j)
{
queue<pair<int, int>> q;
q.push({i, j});
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
flag[i][j] = true;
while(!q.empty())
{
auto tmp = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int new_x = tmp.first + dx[i], new_y = tmp.second + dy[i];
if(new_x < 0 || new_x >= grid.size() || new_y < 0 || new_y >= grid[0].size()) continue;
if(!flag[new_x][new_y] && grid[new_x][new_y] == '1')
{
q.push({new_x, new_y});
flag[new_x][new_y] = true;
}
}
}
}
};
被围绕的区域
题目链接: https://leetcode-cn.com/problems/surrounded-regions/
class Solution {
public:
void solve(vector<vector<char>>& board) {
if(board.empty()) return ;
int n = board.size(), m = board[0].size();
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if((i == 0 || j == 0 || i == n - 1 || j == m - 1) && board[i][j] == 'O')
{
bfs(board, i, j);
}
for(int i = 0; i < n ; i++)
{
for(int j = 0; j < m ; j++)
{
if(board[i][j] == 'O') board[i][j] = 'X';
if(board[i][j] == '#') board[i][j] = 'O';
}
}
}
void bfs(vector<vector<char>>& board, int x, int y)
{
queue<pair<int, int>> q;
q.push({x, y});
board[x][y] = '#';
while(!q.empty())
{
auto tmp = q.front();
q.pop();
x = tmp.first, y = tmp.second;
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
for(int i = 0; i < 4; i++)
{
int new_x = x + dx[i], new_y = y + dy[i];
if(new_x < 0 || new_x >= board.size() || new_y < 0 || new_y >= board[0].size())
continue;
char ch = board[new_x][new_y];
if(ch == 'O')
{
board[new_x][new_y] = '#';
q.push({new_x, new_y});
}
}
}
}
};
DFS
电话号码的字母组合
题目链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
class Solution {
public:
unordered_map<char, string> hashmap;
vector<string> res;
string path;
vector<string> letterCombinations(string digits)
{
if(digits.empty()) return {};
digits2map();
dfs(digits, 0);
return res;
}
void dfs(string digits, int u)
{
if(u == digits.size())
{
res.push_back(path);
return ;
}
char ch = digits[u];
string str = hashmap[ch];
for(auto ch : str)
{
path += ch;
dfs(digits, u + 1);
path.pop_back();
}
}
void digits2map()
{
hashmap['2'] = "abc";
hashmap['3'] = "def";
hashmap['4'] = "ghi";
hashmap['5'] = "jkl";
hashmap['6'] = "mno";
hashmap['7'] = "pqrs";
hashmap['8'] = "tuv";
hashmap['9'] = "wxyz";
}
};
零钱兑换
题目链接:https://leetcode-cn.com/problems/coin-change/
class Solution {
public:
int res = INT_MAX;
int coinChange(vector<int>& coins, int amount) {
sort(coins.rbegin(), coins.rend());
int u = 0;
dfs(coins, 0, amount, u, 0);
return res == INT_MAX ? -1 : res;
}
void dfs(vector<int>& coins, int sum, int amount, int u, int cnt)
{
if(sum == amount)
{
res = min(res, cnt);
return ;
}
if(u == coins.size()) return ;
int target = amount - sum;
for(int i = target / coins[u]; i >= 0 && i + cnt < res; i--)
{
dfs(coins, sum + coins[u] * i, amount, u + 1, cnt + i);
}
}
};
打家劫舍III
题目链接:https://leetcode-cn.com/problems/house-robber-iii/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
if(!root) return 0;
auto res = dfs(root);
//1. 包含当前根节点
//2. 不包含当前根节点
return max(res.first, res.second);
}
pair<int, int> dfs(TreeNode* root)
{
if(!root) return {0, 0};
pair<int, int> res(0, 0);
pair<int, int> l = dfs(root -> left);
pair<int, int> r = dfs(root -> right);
//包含根节点,有左右节点
res.first = l.second + r.second + root -> val;
//不包含根节点,有左右节点
//左1 + 右1; 左1 + 右2;左2 + 右1; 左2 + 右2;
res.second = max(l.first, l.second) + max(r.first, r.second);
return res;
}
};
火柴拼正方形
题目链接:https://leetcode-cn.com/problems/matchsticks-to-square/
class Solution {
public:
bool makesquare(vector<int>& nums) {
//小于4时返回假
if(nums.size() < 4) return false;
//累加求和
int sum = 0;
for(int i = 0; i < nums.size(); i++)
sum += nums[i];
//和不能被4整除肯定不能拼成正方形
if(sum % 4) return false;
//从大到到小排序
sort(nums.rbegin(), nums.rend());
int bucket[4] = {0};
return dfs(0, nums, sum / 4, bucket);
}
//搜索n次,n为元素个数,每次搜索每个桶中应该放的数
bool dfs(int u, vector<int>& nums, int target, int bucket[])
{
if(u >= nums.size())
{
for(int i = 0; i < 4; i++)
if(bucket[i] != target) return false;
return true;
}
for(int i = 0; i < 4; i++)
{
if(bucket[i] + nums[u] > target) continue;
bucket[i] += nums[u];
if(dfs(u + 1, nums, target, bucket)) return true;
bucket[i] -= nums[u];
}
return false;
}
};
括号生成
class Solution {
public:
void dfs(vector<string>& res, string& path, int l, int r, int n)
{
if( l == n && r == n)
{
res.push_back(path);
return;
}
//剪枝
if(l < r) return;
if(l < n)
{
string tmp = path + "(";
dfs(res, tmp, l + 1, r, n);
}
if(r < n)
{
string tmp = path + ")";
dfs(res, tmp, l, r + 1, n);
}
}
vector<string> generateParenthesis(int n) {
vector<string> res;
string str = "";
dfs(res, str, 0, 0, n);
return res;
}
};
知识的价值不在于占有,而在于使用