leetcode每日一题44

news/2024/7/20 22:49:54 标签: leetcode, 算法, 深度优先

130. 被围绕的区域

图论
dfs/bfs
dfs代码框架

void dfs(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本节点所连接的其他节点) {
        处理节点;
        dfs(图,选择的节点); // 递归
        回溯,撤销处理结果
    }
}

思路:本题要求找到被x围绕的陆地,所以边界的陆地O肯定不符合条件。那么我们只要从周边找到陆地O然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地O都变成A,然后再去重新遍历地图的时候,把剩下的O变成X,再把所有的A变成O。

  1. 确认递归函数,参数
    一般情况,深搜需要 二维数组数组结构保存所有路径,需要一维数组保存单一路径,这种保存结果的数组,我们可以定义一个全局变量,避免让我们的函数参数过多。
    因为需要上下左右遍历,所以构建一个方向坐标
    int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1};
    递归函数参数为地图,还有当前坐标x,y
    void dfs(vector<vector<char>>& board, int x, int y)
  2. 确认终止条件
    终止添加不仅是结束本层递归,同时也是我们收获结果的时候。
    另外,其实很多dfs写法,没有写终止条件,其实终止条件写在了, 下面dfs递归的逻辑里了,也就是不符合条件,直接不会向下递归。
    这个代码的终止条件就是写在递归逻辑里的。
    当前方向超出边界,停止当前方向的遍历
for(int i=0;i<4;i++){
	nextx=x+dir[i][0];
	nexty=y+dir[i][1];
	if(nextx<0||nextx>=board.size()||nexty<0||nexty>=board[0].size())
		continue;
	}
  1. 处理目前搜索节点出发的路径
    把当前节点改为A
    没必要回溯,得到坐标且坐标没有过界,则判断该节点是否是X或者A,若是,则停止当前方向的遍历
    若不是,就继续递归
class Solution {
public:
    int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; 
    void dfs(vector<vector<char>>& board, int x, int y){
        board[x][y]='A';
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=board.size()||nexty<0||nexty>=board[0].size())
                continue;
            if(board[nextx][nexty]=='X'||board[nextx][nexty]=='A')
                continue;
            dfs(board, nextx, nexty);
        }
        return;
    }
    void solve(vector<vector<char>>& board) {
        int n=board.size(), m=board[0].size();
        for(int i=0;i<n;i++)
        {
            if(board[i][0]=='O')
                dfs(board,i,0);
            if(board[i][m-1]=='O')
                dfs(board,i,m-1);
        }
        for(int j=0;j<m;j++)
        {
            if(board[0][j]=='O')
                dfs(board,0,j);
            if(board[n-1][j]=='O')
                dfs(board,n-1,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] == 'A') 
                    board[i][j] = 'O';
            }
        return;
    }
};

131. 分割回文串

回溯
切割问题类似组合问题
for循环表示在哪里切下第1刀
递归表示在第一刀的基础上,下面的几刀在哪切

  1. 递归函数的返回值以及参数
    定义两个全局变量,一个用来存放符合条件单一结果,一个用来存放符合条件结果的集合。
    vector<vector<string>> result;
    vector<string> path;
    函数里有两个参数,字符串s,还有记录本层递归的中从哪里开始切的startIndex
    void backtracking (const string& s, int startIndex)
  2. 递归函数终止条件
    字符串切完了就终止,把当前路径存到结果里
if(startIndex>=s.length()){
	result.push_back(path);
	return;
}
  1. 单层搜索的逻辑
    从startIndex开始,遍历startIndex后面所有的位置。如果startIndex到当前位置的字符串是回文子串,则加入当前路径。否则跳过
    然后递归当前位置的下一个位置为下一个递归的startIndex
    递归结束,回溯,弹出当前字符串
for(int i=startIndex; i<s.length();i++)
{
	if(isPalindrome(s, startIndex, i)){
		string str = s.substr(startIndex, i - startIndex + 1);
		path.push_back(str);
	}
	else continue;
	backtracking(s, i+1);
	path.pop_back();
}

然后要写是否是回文子串
双指针,一前一后对比

bool isPalindrome(const string& s, int startIndex, int end)
{
	for(int i=startIndex, int j=end;i<j; i++,j--)
	{
		if(s[i]!=s[j])
			return false;
		}
	return true;
}

整体代码

class Solution {
public:
    bool isPalindrome(const string& s, int startIndex, int end)
    {
        for(int i=startIndex,j=end;i<j; i++,j--)
        {
            if(s[i]!=s[j])
                return false;
            }
        return true;
    }
    vector<vector<string>> result;
    vector<string> path;
    void backtracking (const string& s, int startIndex) 
    {
        if(startIndex>=s.length()){
            result.push_back(path);
            return;
        }
        for(int i=startIndex; i<s.length();i++)
        {
            if(isPalindrome(s, startIndex, i)){
                string str = s.substr(startIndex, i - startIndex + 1);
                path.push_back(str);
            }
            else continue;
            backtracking(s, i+1);
            path.pop_back();
        }
        return;
    }
    vector<vector<string>> partition(string s) {
        result.clear();
        path.clear();
        backtracking(s, 0);
        return result;
    }
};

http://www.niftyadmin.cn/n/5322404.html

相关文章

vue3基础: 组件注册

组件注册 一个 Vue 组件在使用前需要先被“注册”&#xff0c;这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式&#xff1a;全局注册和局部注册。 全局注册 我们可以使用 Vue 应用实例的.component()方法&#xff0c;让组件在当前 Vue 应用中全局可用。 impo…

Hive命令行运行SQL将数据保存到本地如何去除日志信息

1.场景分析 先有需求需要查询hive数仓数据并将结果保存到本地&#xff0c;但是在操作过程中总会有日志信息和表头信息一起保存到本地&#xff0c;不符合业务需要&#xff0c;那如何才能解决该问题呢&#xff1f; 废话不多少&#xff0c;直接上代码介绍&#xff1a; 2.问题解决…

31 树的存储结构一

无法直接用数组表示树的逻辑结构&#xff0c;但是可以设计结构体数组对节点间的关系进行描述&#xff1a;【如表】 这样做的问题&#xff1a; 可以利用 组织链表 parent指针&#xff1a; 注意&#xff1a;树结点在 组织链表 中的位置不代表树的任何逻辑关系 树的架构图&#xf…

MySQL 日志之二进制日志-binlog

1、简介 MySQL 的二进制日志记录了对 MySQL 所有的更改操作&#xff0c;不包括 select 和 show 等操作。二进制日志文件主要有&#xff1a;数据恢复、主从复制、审计&#xff08;判断是否有注入攻击&#xff09;等作用。 2、二进制日志参数配置 2.1、文件参数配置 linux 中 My…

UML-类图和类图转化为代码

提示&#xff1a;文章详细的讲解了类图的四种关系&#xff0c;以及每种关系如何转化为对应的代码。 UML-类图和类图转化为代码 一、类于类之间的关系1.依赖关系2.关联关系(1) 单向关联(2) 双向关联(3) 自关联(4) 聚合关联(has-a)(5) 组合关联&#xff08;contains-a&#xff09…

【MySQL】ANY函数 的巧用(筛选字段 = ANY(语句))

力扣题 1、题目地址 1364. 顾客的可信联系人数量 2、模拟表 顾客表&#xff1a;Customers Column NameTypecustomer_idintcustomer_namevarcharemailvarchar customer_id 是这张表具有唯一值的列。此表的每一行包含了某在线商店顾客的姓名和电子邮件。 联系方式表&#…

力扣每日一练(24-1-13)

如果用列表生成式&#xff0c;可以满足输出的型式&#xff0c;但是不满足题意&#xff1a; nums[:] [i for i in nums if i ! val]return len(nums) 题意要求是&#xff1a; 你需要原地修改数组&#xff0c;并且只使用O(1)的额外空间。这意味着我们不能创建新的列表&#xff…

pytorch-gpu版本安装

前言 PyTorch是一款广泛使用的python深度学习框架&#xff0c;它能够帮助研究者们快速构建和训练复杂的神经网络&#xff0c;在人工智能领域无疑是【宠儿】的存在。 但刚进门的小白们应该都有困惑&#xff1a;为什么有些基于pytorch框架吃CPU&#xff0c;油得却是吃GPU&#xf…