数据结构学习 Leetcode494 目标和

news/2024/7/20 22:01:00 标签: 数据结构, 学习, 深度优先

关键词:动态规划 01背包 dfs回溯

一个套路:

  • 01背包:空间优化之后dp【target+1】,遍历的时候要逆序遍历
  • 完全背包:空间优化之后dp【target+1】,遍历的时候要正序遍历

题目:

解法一:

dfs 回溯

思路:

数组nums 的每个元素都可以添加符号+或-,因此每个元素有⒉种添加符号的方法,n个数共有2^n种添加符号的方法,对应2^n种不同的表达式。当n个元素都添加符号之后,即得到─种表达式,如果表达式的结果等于目标数target,则该表达式即为符合要求的表达式。
可以使用回溯的方法遍历所有的表达式,回溯过程中维护一个计数器count,当遇到一种表达式的结果等于目标数target时,将count的值加1。遍历完所有的表达式之后,即可得到结果等于目标数target的表达式的数目。

因为nums最多只有20,所以暴力的dfs应该是不会爆的。

回顾一下之前的dfs笔记吧!

中止条件:step>nums.size()

count统计符合个数

分出两个dfs,一个给+一个给-

复杂度计算:

时间复杂度O(2^n)

空间复杂度O(n)

代码:

class Solution {
public:
    int findTargetSumWays(std::vector<int>& nums, int target) {
        int count = 0, sum = 0;
        int step = 1;
        dfs(nums, target, step, sum, count);
        return count;
    }
    void dfs(std::vector<int>& nums, int target, int step, int sum, int& count)
    {
        if (step == nums.size() + 1)
        {
            if(sum == target)
                count++;
            return;
        }
        dfs(nums, target, step + 1, sum + nums[step - 1], count);
        dfs(nums, target, step + 1, sum - nums[step - 1], count);
        
    }
};

解法二:

动态规划 01背包

思路:

可以用非常巧的办法转换成用动态规划做。

 得到新的的目标为neg。

之后用01背包的知识就可以完成。

状态:dp[j]:前i个元素中,凑到目标j的方法总数。

转移方程:dp[j]=dp[j]+dp[j-nums[i]]

  • dp[j]:不需要第i个元素nums[i]的情况下,凑到目标j的方法总数。
  • dp[j-nums[i]]:需要第i个元素nums[i]的情况下,凑到目标j的方法总数。

初始条件:因为是计算总和所以设置为0

边界:dp[0]=1 前0个元素,凑到目标0的方法总数为1

复杂度计算:

时间复杂度O(nm) n=neg m=nums.size()

空间复杂度O(n) n=neg

代码:

class Solution {
public:
    int findTargetSumWays(std::vector<int>& nums, int target) {
        int sum = 0;
        for (const auto& x : nums)
            sum += x;
        int diff = sum - target;
        if (diff < 0 || diff & 1)
            return 0;
        int tar = diff / 2;
        std::vector<int> dp(tar + 1);
        //边界条件:当没有任何元素可以选取时,元素和只能是 0,对应的方案数是 1
        dp[0] = 1;//装0个重量,用0个装,一共有一种方法
        for (int i = 0; i < nums.size(); ++i)
        {
            for (int j = tar; j >= nums[i]; --j)
            {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[tar];
    }
};


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

相关文章

Vue框架引入Axios

首先已经创建好了 Vue 框架&#xff0c;安装好了 node.js。 没有完成的可按照此博客搭建&#xff1a;搭建Vue项目 之后打开终端&#xff0c;使用命令。 1、命令安装 axios 和 vue-axios npm install axios --save npm install vue-axios --save2、package.json 查看版本 在 p…

浏览器Post请求出现413 Request Entity Too Large (Nginx)

环境 操作系统 window server 2016 前端项目 Vue2 Nginx-1.25.3 一、错误信息 前端是vue项目&#xff0c;打包后部署在Nginx上&#xff0c;前端post请求出现Request Entity Too Large错误信息。 ​这种问题一般是请求实体太大&#xff08;包含参数&#xff0c;文件等&#xf…

netty源码:(40)ReplayingDecoder

ReplayingDecoder是ByteToMessageDecoder的子类&#xff0c;我们继承这个类时&#xff0c;也要实现decode方法&#xff0c;示例如下&#xff1a; package cn.edu.tju;import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handle…

模型部署之——ONNX模型转RKNN

提示&#xff1a;这里可以添加学习目标 提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、加载Docker镜像二、转换脚本 一、加载Docker镜像 加载rknn官方提供的基于x86架构下模型转换的镜像文件&#xff0c;生成…

F (1164) : B DS二叉排序树_有效的二叉排序树

Description 给你一个二叉树&#xff0c;判断其是否是一个有效的二叉排序树。 有效的二叉排序树定义如下&#xff1a; 1. 结点的左子树只包含小于当前结点的数。 2. 结点的右子树只包含大于当前结点的数。 3. 所有左子树和右子树自身必须也是二叉排序树。 Input 第一行输…

HTTP协议与消息加密

问题引出 在使用企业微信Api的接口时&#xff0c;发现获取 access_token 的接口&#xff0c;传递参数使用的是 查询参数&#xff08;Query参数&#xff09;。于是我产生了疑问&#xff0c;通过 Query参数 传递的参数&#xff0c;安全吗&#xff1f;会不会产生泄露&#xff0c;…

【基于VirtualBox及openEuler20.03 TLS SP1编译openGauss2.1.0源码】

【openEuler 20.03 TLS编译openGauss2.1.0源码】 一、安装环境二、安装步骤 一、安装环境 项目Value虚拟机virtualbox操作系统openEuler 20.03 TLSopenGauss2.1.0openGauss-third_party2.1.0 二、安装步骤 以下操作需要在root用户下执行 编辑/etc/selinux/config vim /etc/s…

元道经纬相机信息化赋能光伏电站运维管理

近年来&#xff0c;我国光伏产业高速发展&#xff0c;尤其以分布式光伏发电项目增长迅速&#xff0c;为更好服务新能源发电&#xff0c;大力推广电能替代。与此同时&#xff0c;电力企业亟需改变落后的管理模式&#xff0c;借助信息化软件提升管理效率。 为了进一步提升光伏电…