leetcode每日一题39

news2024/11/29 6:39:12

122.买卖股票的最佳时机II

  1. 确定dp数组(dp table)以及下标的含义
    dp[i][j] j=0 不持有股票
    j=1持有股票
    i:第i天
    dp[i][j]:第i天,持有状态为j时的最大现金
  2. 确定递推公式
    dp[i][0]=max(dp[i-1][0], dp[i-1][1]+prices[i]);
    第i天不持有股票,那可以是前一天持有股票然后卖出去了,和前一天就不持有股票
    dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i];
    第i天持有股票,可以是前一天就持有股票,或者前一天不持有,今天买入
  3. dp数组如何初始化
    dp[0][0]=0;
    dp[0][1]=-prices[0];
  4. 确定遍历顺序
    从左到右,没啥好说的
for(int i=1;i<prices.size();i++){
	dp[i][0]=max(dp[i-1][0], dp[i-1][1]+prices[i]);
	dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
  1. 举例推导dp数组

最后代码如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(2,0));
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        for(int i=1;i<prices.size();i++){
            dp[i][0]=max(dp[i-1][0], dp[i-1][1]+prices[i]);
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
        }
        
        return dp[prices.size()-1][0];
    }
};

93.复原ip地址

相当于分割字符串,而且要返回的是所有的分割方法
那就是回溯了
分割问题可以使用回溯搜索法把所有可能性搜出来

  1. 确定递归参数
    需要一个全局变量的vector<string>保存所有的回溯结果
    需要字符串s
    因为不能重复分割,所以需要一个startIndex
    还需要一个记录当前是第几个分割点的pointNum,因为只能分割成4段
    不需要递归结束后计算什么,所以不需要返回值
vector<string> result;
void backtracking(string& s, int startIndex,int pointNum)
  1. 确定递归终止条件
    一共只能切成四段,所以pointNum==3的时候,就会终止递归。不过此时还得判断一下最后一段是否合法,合法才能加进结果集
if(pointNum==3)
{
	if(isValid(s,startIndex,s.size()-1))
		result.push_back(s);
}
  1. 单层搜索的逻辑
    判断[startIndex, i]是否合法,合法就加上’.‘,分割该字串,然后递归下一层,因为字符串加上了一个’.',pointNum++,所以下一个递归的startIndex应该从i+2开始。不合法就结束本层
for(int i=startIndex;i<s.size();i++)
{
	if(isValid(s,startIndex,i)){
		s.insert(s.begin()+i+1,'.');
		pointNum++;
		backtracking(s,i+2,pointNum);
		pointNum--;
		s.erase(s.begin()+i+1);
}else break;

接下来写一下如何判断字符串合法
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0)
那就是s[start]=='0’且start!=end,false
s[i] > ‘9’ || s[i] < ‘0’ false
num>255 false

bool isValid(string s,int start, int end)
{
	if(s[start]=='0'&& start != end)
		return false;
	int num=0;
	for(int i=start;i<=end;i++){
		if(s[i] > '9' || s[i] < '0')
			return false;
		num = num * 10 + (s[i] - '0');
        if (num > 255) { // 如果大于255了不合法
            return false;
        }
    }
    return true;
}

不过还存在另一种不合法的情况
当s="101023"时,我的代码输出了[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“10.10.23.”,“10.102.3.”,“101.0.2.3”,“101.0.23.”]
而预期结果是[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“10.10.23.”,“10.102.3.”,“101.0.2.3”,“101.0.23.”]
可以看到我的代码在字符串结尾加了分割
这是因为回溯的时候,i+2有可能大于s.size()
所以要判定一下start和end的大小

bool isValid(string s,int start, int end)
{
	if(start>end)
		return false;
	if(s[start]=='0'&& start != end)
		return false;
	int num=0;
	for(int i=start;i<=end;i++){
		if(s[i] > '9' || s[i] < '0')
			return false;
		num = num * 10 + (s[i] - '0');
        if (num > 255) { // 如果大于255了不合法
            return false;
        }
    }
    return true;
}

整体代码:

class Solution {
public:
    bool isValid(string s,int start, int end)
    {
        if (start > end) {
            return false;
        }
        if(s[start]=='0'&& start != end)
            return false;
        int num=0;
        for(int i=start;i<=end;i++){
            if(s[i] > '9' || s[i] < '0')
                return false;
            num = num * 10 + (s[i] - '0');
            if (num > 255) { // 如果大于255了不合法
                return false;
            }
        }
        return true;
    }
    vector<string> result;
    void backtracking(string& s, int startIndex, int pointNum) {
        if (pointNum == 3) {
            if (isValid(s, startIndex, s.size() - 1))
                result.push_back(s);
            return;
        }

        for (int i = startIndex; i < s.size(); i++) {
            if (isValid(s, startIndex, i)) {
                s.insert(s.begin() + i + 1, '.');
                pointNum++;
                backtracking(s, i + 2, pointNum);
                pointNum--;
                s.erase(s.begin() + i + 1);
            } else {
                break;
            }
        }
    }

    vector<string> restoreIpAddresses(string s) {
        backtracking(s,0,0);
        return result;
    }
};

96.不同的二叉搜索树

要返回满足题意的二叉搜索树种类数
同时呢,n个节点的二叉搜索树的构建可以由n-1个节点的二叉搜索树推导出来
所以是DP

  1. 确定dp数组(dp table)以及下标的含义
    在这里插入图片描述如图,头节点为1时,其左子树节点数量为0,右子树节点数量为2,节点数为0有1种构建方式,节点数为2有两种构建方式,所以头节点为1时,有1*2种构建方式
    那么我们可以令dp[i]为当节点数为i时,有几种不同的构建方式

  2. 确定递推公式

dp[i]+=dp[j-1]*dp[i-j],j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

  1. dp数组如何初始化

节点数为0有1种构建方式

dp[0]=1;
  1. 确定遍历顺序
for(int i=1;i<=n;i++)
	for(int j=1;j<=i;j++)
		dp[i]+=dp[j-1]*dp[i-j];
  1. 举例推导dp数组

最后代码如下:

class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n+1,0);
        dp[0]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                dp[i]+=dp[j-1]*dp[i-j];
        return dp[n];
    }
};

95.不同的二叉搜索树II

这道题要返回所有的二叉搜索树了,那就是回溯了
涉及到树,后序遍历

  1. 确定递归参数
    因为要对返回的左右子树的结果构造二叉平衡树,所以需要返回值,返回值为当前构造的树的根节点的集(因为可以有多个节点都可做当前子树的根节点
    因为要构建左右子树,且是平衡二叉树,所以从[left,right]中选数字i作为根节点,[left,i-1]就是左子树可选节点,[i+1,right]就是右子树可选节点
vector<TreeNode*> backtracking(int left,int right)
  1. 回溯函数终止条件
    当left>right时,就没法产生子树了,也就返回空节点
if(left>right)
{
    ans.push_back(nullptr);
    return ans;
}
  1. 回溯搜索的遍历过程
    在[left,right]中遍历每一个i,作为根节点
    先得到左右子树根节点的候选集
vector<TreeNode*> left_nodes=backtracking(left,i-1);
vector<TreeNode*> right_nodes=backtracking(i+1,right);

i左边的序列可以作为左子树结点,且左儿子可能有多个,所以有vector<TreeNode *> left_nodes = generate(left, i - 1);;
i右边的序列可以作为右子树结点,同上所以有vector<TreeNode *> right_nodes = generate(i + 1, right);;

因此,产生的以当前i为根结点的子树有left_nodes.size() * right_nodes.size()个,遍历每种情况,即可生成以i为根节点的子树序列;

for(TreeNode* left_node:left_nodes)
    for(TreeNode* right_node:right_nodes)
    {
        TreeNode* tmp=new TreeNode(i);
        tmp->left=left_node;
        tmp->right=right_node;
        ans.push_back(tmp);
    }

即:

for(int i=left;i<=right;i++){
   vector<TreeNode*> left_nodes=backtracking(left,i-1);
   vector<TreeNode*> right_nodes=backtracking(i+1,right);
   for(TreeNode* left_node:left_nodes)
       for(TreeNode* right_node:right_nodes)
       {
           TreeNode* tmp=new TreeNode(i);
           tmp->left=left_node;
           tmp->right=right_node;
           ans.push_back(tmp);
       }
}

整理得到整个代码:

class Solution {
public:
    vector<TreeNode*> backtracking(int left,int right){
        vector<TreeNode *> ans;
        if(left>right)
        {
            ans.push_back(nullptr);
            return ans;
        }
        for(int i=left;i<=right;i++){
            vector<TreeNode*> left_nodes=backtracking(left,i-1);
            vector<TreeNode*> right_nodes=backtracking(i+1,right);
            for(TreeNode* left_node:left_nodes)
                for(TreeNode* right_node:right_nodes)
                {
                    TreeNode* tmp=new TreeNode(i);
                    tmp->left=left_node;
                    tmp->right=right_node;
                    ans.push_back(tmp);
                }
        }
        return ans;
    }
    vector<TreeNode*> generateTrees(int n) {
        return backtracking(1,n);
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1300026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux权限(用户角色+文件权限属性)

Linux权限 文章目录 Linux权限一.文件权限1.快速掌握修改权限的方法&#xff08;修改文件权限属性&#xff09;2.对比权限的有无&#xff0c;以及具体的体现3.修改权限的第二套方法&#xff08;修改用户角色&#xff09;4.文件类型&#xff08;Linux下一切皆文件&#xff09; 二…

编辑拒稿理由是重复率高

大家好&#xff0c;今天来聊聊编辑拒稿理由是重复率高&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 编辑拒稿理由是重复率高 当作者提交论文到学术期刊后&#xff0c;编辑会对论文进行审核小发猫写作…

Vue3: 给表格多个字段添加排序功能

问题 在Vue3项目中&#xff0c;使用element-plus的表格组件绘制表格后&#xff0c;需要令表格的多个字段可以进行选择排序&#xff08;选择升序或者降序&#xff09;但是排序功能好像有时候会出错&#xff0c;需要排序的字段多了之后&#xff0c;排序功能有时候会不起作用 解…

算法专题一:双指针

算法专题一&#xff1a;双指针 一&#xff1a;移动零1.GIF题目解析&#xff1a; 二&#xff1a;复写零2.GIF题目解析&#xff1a; 三&#xff1a;快乐数3.GIF题目解析&#xff1a; 四&#xff1a;装水最多容器&#xff1a;4.GIF题目解析&#xff1a; 五&#xff1a;有效三角形的…

知识产权服务企业网站建设效果如何

知识产权服务也有较高的市场需求度&#xff0c;尤其如今互联网深入到各个行业&#xff0c;无论个人还是企业都会以不同的方式经营&#xff0c;相应的为保障自身权益&#xff0c;注册商标、专利等自然不可少&#xff0c;而对普通小白来说&#xff0c;想要完成这些流程也是有些难…

NSSCTF-Crypto靶场练习--第11-20题wp

文章目录 [SWPUCTF 2021 新生赛]traditional[LitCTF 2023]梦想是红色的 (初级)[SWPUCTF 2021 新生赛]crypto2[羊城杯 2021]Bigrsa[LitCTF 2023]Hex&#xff1f;Hex&#xff01;(初级)[SWPU 2020]happy[AFCTF 2018]BASE[安洵杯 2019]JustBase[鹤城杯 2021]Crazy_Rsa_Tech[SWPUCT…

mybatisPlus框架

1、特性 无侵入 &#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑 损耗小 &#xff1a;启动即会自动注入基本 CURD &#xff0c;性能基本无损耗&#xff0c;直接面向对象操作 强大的 CRUD 操作 &#xff1a;内置通用 Mapper 、…

Oracle(2-12)User-Managed Complete Recovery

文章目录 一、基础知识1、Media Recovery 介质恢复2、Recovery Steps 恢复步骤3、恢复4、Recovery in ARCHIVELOG 在ARCHIVELOG中恢复5、Complete Recovery完全恢复6、CR in ARCHIVELOG Mode 归档日志模式下的完全恢复7、Determine Files Need Recovery确定需要恢复的文件8、Ab…

JDK8新特性:Lambda表达式规则及用法,方法引用

目录 Lambda表达式是JDK8新增的一种语法格式 1.作用 2.用法规则&#xff1a; 3.方法引用 Lambda表达式是JDK8新增的一种语法格式 1.作用 简化匿名内部类的代码写法 Lambad用法前提&#xff1a;只能简化函数式接口&#xff08;一般加有Funcationallnterface&#xff09;&a…

2023年11月10日 Go生态洞察:十四年Go的成长之路

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

STL(八)(总结篇)

###以四道题来总结 题号:lanqiao OJ 3226 1.宝藏排序II ### 这道题主要考察sort,非常简单输出就是升序不需要自定义比较函数 #include<bits/stdc.h> using namespace std; const int N1e55; //这里用int就足够了不需要开long long int a[N]; int main(){ios::sync_with…

TCP的滑动窗口机制

网络的错误检测和补偿机制非常复杂。 一、等待超时时间&#xff08;返回ACK号的等待时间&#xff09; 当网络繁忙时会发生拥塞&#xff0c;ACK号的返回变慢&#xff0c;较短的等待时间会导致频繁的数据重传&#xff0c;导致本就拥塞的网络雪上加霜。如果等待时间过长&#xf…

查看mysql是否开启远程端口

这个命令&#xff1a; sudo netstat -tlnp | grep mysqld如果是 就说明只开启了本地的&#xff0c;要更改这个设置&#xff0c;你需要编辑 MySQL 的配置文件&#xff0c;并确保 bind-address 设置为 0.0.0.0。打开 MySQL 的配置文件&#xff08;通常是 /etc/mysql/mysql.conf…

二叉排序树的判断(二叉树的顺序存储):2022年408算法题

对于采用顺序存储方式保存的二叉树&#xff0c;根结点保存在SqBiTNode[0]中&#xff1b;当某结点保存SqBiTNode[i]中时&#xff0c;若有左孩子&#xff0c;则其值保存在SqBiTNode [2i1]中&#xff1b;若有右孩子&#xff0c;则其值保存在SqBiTNode[2i2]中&#xff1b;若有双亲结…

SD之lora训练

目录 为什么要训练自己的模型 SD模型微调方法 准备素材 1 确定要训练的LoRA类型 2 图片收集 3 图片预处理 4 图片标注 安装Koyha_ss 训练lora 1.准备参数和环境 2.启动训练 使用模型 1 拷贝训练过的lora模型 2 启动SD WebUI进行图像生成 为什么要训练自己的模型 …

来聊聊java8的数值流

简介 java8为我提供的简单快捷的数值流计算API&#xff0c;本文就基于几个常见的场景介绍一下数值流API的使用。 基础示例 我们以一个食物热量计算的功能展开演示&#xff0c;如下所示&#xff0c;可以看到Dish类它记录了每一个食物的名称、热量、类型等信息: public class…

百科词条可以删除吗?如何删除自己的百度百科?

近日&#xff0c;小马识途营销顾问接到不少客户删除自己百科词条的咨询&#xff0c;有不少人自己并没有去建立百科词条&#xff0c;但是网上已经有了&#xff0c;有的信息不正确&#xff0c;甚至有的信息是负能量的&#xff0c;对当事人自己造成一定的困扰&#xff0c;所以寻求…

【Proteus仿真】【51单片机】光照强度检测系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使共阴数码管&#xff0c;PCF8591 ADC模块、光敏传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;数码管显示光传感器采集光照强度值&#xff…

在线测试http接口,为您解析最佳测试方法

您是否正在寻找一种方便、高效且可靠的方法来测试您的http接口&#xff1f;在这篇文章中&#xff0c;我们将为您介绍在线测试http接口的最佳方法&#xff0c;帮助您确保您的接口在各种情况下都能正常运行。 什么是http接口&#xff1f; 在开始介绍如何测试http接口之前&#x…

json精讲

本文介绍json的规范及javascript和java对数据的交换读取 1. json介绍1.1 json简介1.2为什么使用 JSON&#xff1f; 2. json规范2.1基础规范2.2 key值为-字符串、数字、布尔值2.3 key值为对象Object2.4 key值为数组2.5 json本身就是一个数组 3.javascript操作json3.1 javascript…