题目来源于知识星球—英雄算法联盟,五月算法集训专题
目录
前言
跟随英雄算法联盟博主—英雄哪里出来,每天完成相应的算法练习,一个月后,必定会有所成长!
一、565.数组嵌套(中等)
1.题目描述
2.解题思路
想象成N个节点,每个节点都有一条出边,采用染色法,遍历所有节点,将没被
染色的节点进行访问并计数,得到计数的最大值。
3.代码演示(C++)
class Solution
{
int Max, Cnt;
int hash[200010];
void dfs(vector<int>& nums, int u, int color)
{
if(hash[u] != -1)
{
return ;
}
hash[u] = color;
++Cnt;
dfs(nums, nums[u], color);
}
public:
int arrayNesting(vector<int>& nums)
{
int i;
int n = nums.size();
int color = 0;
Max = 0;
memset(hash, -1, sizeof(hash));
for(i = 0; i < n; ++i)
{
if(-1 == hash[i])
{
Cnt = 0;
dfs(nums, i, ++color);
Max = max(Max, Cnt);
}
}
return Max;
}
};
4.题目链接
二、401.二进制手表(简单)
1.题目描述
2.解题思路
共有10个位置,每个位置都是选或不选,枚举所有情况,分别记录时间,
转换成字符串。
3.代码演示(C++)
class Solution
{
vector<string> ans;
int stk[10], top;
int hv[4] =
{
8, 4, 2, 1
};
int mv[6] =
{
32, 16, 8, 4, 2, 1
};
string totime(int h, int m)
{
string ans = "";
if(h <= 9)
{
ans += h + '0';
}
else
{
ans += h/10 + '0';
ans += h % 10 + '0';
}
ans += ":";
ans += m/10 + '0';
ans += m%10 + '0';
return ans;
}
void dfs(int deng, int maxDeng, int light, int maxLight)
{
if(deng == maxDeng)
{
if(light == maxLight)
{
int h = 0, m = 0;
for(int i = 0; i < top; ++i)
{
int x = stk[i];
if(x <= 3)
{
h += hv[x];
}
else
{
m += mv[x-4];
}
}
if(h <= 11 && m <= 59)
{
ans.push_back( totime(h, m) );
}
}
return ;
}
if(light > maxLight)
{
return ;
}
dfs(deng+1, maxDeng, light, maxLight);
stk[top++] = deng;
dfs(deng+1, maxDeng, light + 1, maxLight);
--top;
}
public:
vector<string> readBinaryWatch(int turnedOn)
{
top = 0;
ans.clear();
dfs(0, 10, 0, turnedOn);
return ans;
}
};
4.题目链接
三、1079.活字印刷(中等)
1.题目描述
2.解题思路
枚举一个长度,再枚举长度对应的元素的全排列,利用字符串进行判断计数。
3.代码演示(C++)
class Solution
{
unordered_map<string, bool> rethash;
bool visited[26];
char stk[10], top;
int cnt;
void dfs(string& tiles, int depth, int maxDepth)
{
if(depth == maxDepth)
{
stk[top] = '\0';
if(rethash.find(stk) == rethash.end())
{
rethash[stk] = true;
++cnt;
}
return ;
}
int i, n = tiles.size();
for(i = 0; i < n; ++i)
{
if(!visited[i])
{
visited[i] = true;
stk[top++] = tiles[i];
dfs(tiles, depth + 1, maxDepth);
--top;
visited[i] = false;
}
}
}
public:
int numTilePossibilities(string tiles)
{
int i;
rethash.clear();
memset(visited, false, sizeof(visited));
cnt = 0;
top = 0;
for(i = 1; i <= tiles.size(); ++i)
{
dfs(tiles, 0, i);
}
return cnt;
}
};
4.题目链接
四、1219.黄金矿工(中等)
1.题目描述
2.解题思路
枚举一个可能有金矿的位置,枚举四个方向,判断边界和障碍,再递归调用,
找到最长路即可。
3.代码演示(C++)
class Solution
{
int hash[16][16];
int maxv;
int dir[4][2] =
{
{0, 1}, {1, 0}, {0, -1}, {-1, 0}
};
void dfs(vector<vector<int>>& grid, int m, int n, int x, int y, int sum)
{
maxv = max(maxv, sum);
for(int i = 0; i < 4; ++i)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx < 0 || ty < 0 || tx == m || ty == n)
{
continue;
}
if(grid[tx][ty] == 0)
{
continue;
}
if(!hash[tx][ty])
{
hash[tx][ty] = 1;
dfs(grid, m, n, tx, ty, sum + grid[tx][ty]);
hash[tx][ty] = 0;
}
}
}
public:
int getMaximumGold(vector<vector<int>>& grid)
{
int n, m;
int i, j;
int ret = 0;
memset(hash, 0, sizeof(hash));
m = grid.size();
n = grid[0].size();
for(i = 0; i < m; ++i)
{
for(j = 0; j < n; ++j)
{
if(grid[i][j])
{
hash[i][j] = 1;
maxv = 0;
dfs(grid, m, n, i, j, grid[i][j]);
ret = max(ret, maxv);
hash[i][j] = 0;
}
}
}
return ret;
}
};
4.题目链接
总结
每天跟随英雄哥学习相关的算法,一个月会收获很多,如果你想了解更多关于知识星球的内容,欢迎联系我!