文章目录
一、565. 数组嵌套
1.原题链接
2.题目描述
索引从0开始长度为N的数组A,包含0到N - 1的所有整数。找到最大的集合S并返回其大小,其中 S[i] = {A[i], A[A[i]], A[A[A[i]]], … }且遵守以下的规则。假设选择索引为i的元素A[i]为S的第一个元素,S的下一个元素应该是A[A[i]],之后是A[A[A[i]]]… 以此类推,不断添加直到S出现重复的元素。
3.解题思路
深度优先搜索
4.源码
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int n = nums.size();
vector<bool> used(n,false);
int res = 0;
for(int i = 0;i<n;i++){
if(!used[i]){
res = max(res,dfs(nums,used,i,n));
}
}
return res;
}
int dfs(vector<int>& nums,vector<bool>& used,int &i,int &n){
if(i>=n){
return 0;
}
if(used[i]){
return 0;
}
used[i] = true;
return 1 + dfs(nums,used,nums[i],n);
}
};
二、401. 二进制手表
1.原题链接
2.题目描述
二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。
3.解题思路
枚举所有 2^10=1024 种灯的开闭组合,即用一个二进制数表示灯的开闭,其高 4位为小时,低 6 位为分钟。若小时和分钟的值均在合法范围内,且二进制中 1 的个数为 turnedOn,则将其加入到答案中。
4.源码
class Solution {
public:
vector<string> readBinaryWatch(int turnedOn) {
vector<string> ans;
for (int i = 0; i < 1024; ++i) {
int h = i >> 6, m = i & 63; // 用位运算取出高 4 位和低 6 位
if (h < 12 && m < 60 && __builtin_popcount(i) == turnedOn) {
ans.push_back(to_string(h) + ":" + (m < 10 ? "0" : "") + to_string(m));
}
}
return ans;
}
};
三、1079. 活字印刷
1.原题链接
2.题目描述
你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。注意:本题中,每个活字字模只能使用一次。
3.解题思路
哈希数组加回溯
4.源码
class Solution {
public:
int res;
void dfs(map<char, int>& hash) {
for (auto& data : hash) {
if (data.second > 0) {
data.second--;
res++;
dfs(hash);
data.second++;
}
}
}
int numTilePossibilities(string tiles) {
map<char, int> hash;
for (int i = 0; i < tiles.size(); i++) {
hash[tiles[i]]++;
}
dfs(hash);
return res;
}
};
四、1219. 黄金矿工
1.原题链接
2.题目描述
你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。为了使收益最大化,矿工需要按以下规则来开采黄金:每当矿工进入一个单元,就会收集该单元格中的所有黄金。矿工每次可以从当前位置向上下左右四个方向走。每个单元格只能被开采(进入)一次。不得开采(进入)黄金数目为 0 的单元格。矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。
3.解题思路
深度优先记忆化搜索
4.源码
class Solution {
public:
int maxv = 0, tsum = 0;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
void dfs(int tx, int ty, vector<vector<int>>& grid) {
if (tx < 0 || ty < 0 || tx >= grid.size() || ty >= grid[0].size() || grid[tx][ty] == 0) return ;
int temp = grid[tx][ty];
tsum += temp;
maxv = max(maxv, tsum);
grid[tx][ty] = 0;
for (int i=0; i<4; i++) {
int px = tx + dx[i];
int py = ty + dy[i];
dfs(px, py, grid);
}
grid[tx][ty] = temp;
tsum -= temp;
}
int getMaximumGold(vector<vector<int>>& grid) {
for (int i=0; i<grid.size(); i++)
for (int j=0; j<grid[i].size(); j++)
if (grid[i][j] != 0)
dfs(i, j, grid);
return maxv;
}
};
总结
第十五天,任务过半,还需加油。