栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

五月集训(第十五日)深度优先搜索

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

五月集训(第十五日)深度优先搜索

文章目录
  • 一、565. 数组嵌套
    • 1.原题链接
    • 2.题目描述
    • 3.解题思路
    • 4.源码
  • 二、401. 二进制手表
    • 1.原题链接
    • 2.题目描述
    • 3.解题思路
    • 4.源码
  • 三、1079. 活字印刷
    • 1.原题链接
    • 2.题目描述
    • 3.解题思路
    • 4.源码
  • 四、1219. 黄金矿工
    • 1.原题链接
    • 2.题目描述
    • 3.解题思路
    • 4.源码
  • 总结

一、565. 数组嵌套 1.原题链接

565. 数组嵌套

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& nums) {
        int n = nums.size();
        vector used(n,false);
        int res = 0;
        for(int i = 0;i
            if(!used[i]){
                res = max(res,dfs(nums,used,i,n));
            }
        }
        return res;
    }

    int dfs(vector& nums,vector& 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.原题链接

401. 二进制手表

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 readBinaryWatch(int turnedOn) {
        vector 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.原题链接

1079. 活字印刷

2.题目描述

        你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。注意:本题中,每个活字字模只能使用一次。

3.解题思路

        哈希数组加回溯

4.源码
class Solution {
public:
    int res;

    void dfs(map& hash) {
        for (auto& data : hash) {
            if (data.second > 0) {
                data.second--;
                res++;
                dfs(hash);
                data.second++;
            }
        }
    }

    int numTilePossibilities(string tiles) {
        map hash;
        for (int i = 0; i < tiles.size(); i++) {
            hash[tiles[i]]++;
        }
        dfs(hash);
        return res;
    }
};
四、1219. 黄金矿工 1.原题链接

1219. 黄金矿工

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>& 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>& grid) {
        for (int i=0; i 
总结 

        第十五天,任务过半,还需加油。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/890023.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号