刷题28-30(力扣0322/0078/0221)

0322. 零钱兑换 

题目:

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的。

基本思路:将金币从大到小开始排列,先拿最大的,再拿后面次大的,以此类推。【失败】

class Solution {
public:int coinChange(vector<int>& coins, int amount) {sort(coins.begin(),coins.end());int size=coins.size();if(amount==0) return 0;int ans=0;int remains=amount;for(int i=size-1;i>=0;i--){while(remains>=coins[i]){remains-=coins[i];ans++;}}return (remains>0)?-1:ans;}
};

但显然有bug,思考一顿发现,他可能不需要最后一个,可以是倒数第二个拼起来 ,例如上面这个例子3+4可以出现7但运行时依然把5放上了:

所以进行改进: 如果再进行一层遍历,便从哪一个开始,显然复杂度太高。

这个时候想到了,动态规划

创建了一个长度为 amount+1 的数组 dp,dp[i] 表示凑齐金额 i 所需的最少硬币数目。然后通过迭代更新 dp 数组,最终返回 dp[amount]。如果 dp[amount] 大于 amount,则表示无法凑出总金额,返回 -1。

代码:

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount + 1, amount + 1);dp[0] = 0; // if(amount==0)return 0;for (int i = 1; i <=amount; i++) {for (int j = 0; j < coins.size(); j++) {if (coins[j] <= i)//硬币数值小于总数dp[i] = min(dp[i],dp[i-coins[j]]+1);//可以选择放还是不放。}}return dp[amount]>amount?-1:dp[amount];}
};

每一次dp都可以选择放还是不放。不放就是dp[i]=dp[i];放的话,首先数量要+1,谁的数量呢?是(当前存放金钱总额-放入的金币额 )所需的数量加1。

vector<int> dp(amount + 1, amount + 1);

创建了一个名为 dp 的整型向量(vector),并初始化该向量的大小为 amount + 1,所有元素的初始值都设置为 amount + 1

具体来说,这行代码创建了一个大小为 amount + 1 的整型向量 dp,并且用 amount + 1 来填充所有的元素。在动态规划问题中,通常会使用类似这样的数组来记录中间状态或者保存子问题的解,以便后续计算。在这个特定的动态规划问题中,dp[i] 代表凑齐金额 i 所需的最少硬币数量,初始值设为 amount + 1 也是为了确保后续更新时能正确比较和更新数值。

本题over


78. 子集

题目:

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

思路:这道题自己想的就是遍历。思考用两层for循环,控制左右界限,放之间的元素。后来的时候,又看到一个题解

遍历枚举:

大概意思是:最外层遍历数组的元素,内层循环:复制上一步的子集,然后将当前元素加到复制的子集里面 ,构成新的子集。

举个例子:比如{1,2,3} :
  • 我先产生{1}的子集--》ans={{},{1}},
  • 我复制这个子集subset={{},{1}};此时数组元素遍历到‘2’;
  • 把‘2‘’这个元素加到subset里面subset={{2},{1,2}};
  • 把subset’这个元素加到ans里面此时ans={{},{1},{2},{1,2}}
  • 3同理  1)subset={{},{1},{2},{1,2}};2)subset={{3},{1,3},{2,3},{1,2,3}}
  • 3)ans={{},{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3}}
代码 
class Solution {
public:// 生成一个整数数组的所有可能子集vector<vector<int>> subsets(vector<int>& nums) {// 初始化结果集,包含空集vector<vector<int>> ans = {{}};// 遍历原数组中的每个元素for (int num : nums) {// 获取当前结果集的大小int n = ans.size();// 遍历当前结果集中的每个子集for (int i = 0; i < n; ++i) {// 复制当前子集vector<int> subset = ans[i];// 将当前元素加入子集中subset.push_back(num);// 将更新后的子集加入结果集ans.push_back(subset);}}// 返回生成的所有子集return ans;}
};

二进制位法 

还有使用二进制位来编写的,看了半天没看懂,后来求助解释一下吧

  • 对于长度为 n 的原始数组,通过遍历 0 到 2^n - 1 的所有数字,可以表示所有可能的子集。
  • 在内层循环中,根据当前数字 i 的二进制表示中的 1,将对应位置的元素加入当前子集。
  • 最终将每个生成的子集添加到结果集中,得到所有可能的子集
举个例子
当我们具体遍历生成子集的过程时,以数组 {3,2,1} 为例:当 i = 0 时,二进制表示为 000,对应空集 {}。内层循环不执行,因为没有任何元素被选中。
当 i = 1 时,二进制表示为 001,对应子集 {3}。内层循环执行,检查第 0 位是否为 1,发现是,将 nums[0](即 3)加入到当前子集中。
当 i = 2 时,二进制表示为 010,对应子集 {2}。内层循环执行,检查第 1 位是否为 1,发现是,将 nums[1](即 2)加入到当前子集中。
当 i = 3 时,二进制表示为 011,对应子集 {2, 3}。内层循环执行,检查第 0 和第 1 位是否为 1,发现都是,将 nums[0] 和 nums[1] 加入到当前子集中。
当 i = 4 时,二进制表示为 100,对应子集 {1}。内层循环执行,检查第 2 位是否为 1,发现是,将 nums[2](即 1)加入到当前子集中。
当 i = 5 时,二进制表示为 101,对应子集 {1, 3}。内层循环执行,检查第 0 和第 2 位是否为 1,发现第 0 位和第 2 位为 1,将 nums[0] 和 nums[2] 加入到当前子集中。
当 i = 6 时,二进制表示为 110,对应子集 {1, 2}。内层循环执行,检查第 1 和第 2 位是否为 1,发现第 1 位和第 2 位为 1,将 nums[1] 和 nums[2] 加入到当前子集中。
当 i = 7 时,二进制表示为 111,对应子集 {1, 2, 3}。内层循环执行,检查所有位都为 1,将所有元素 {1, 2, 3} 加入到当前子集中。
通过这样的遍历过程,我们可以逐步生成出数组 {1, 2, 3} 的所有可能子集。
代码: 
class Solution {
public:vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> ans; // 存储所有可能的子集int n = nums.size(); // 原始数组的长度// 遍历所有可能的子集长度for (int i = 0; i < (1 << n); i++) {vector<int> subset; // 当前子集// 对于每个子集长度,遍历原始数组for (int j = 0; j < n; j++) {// 检查第 j 位是否在当前子集中if (i & (1 << j)) {subset.push_back(nums[j]); // 将元素加入当前子集}}ans.push_back(subset); // 将当前子集加入结果集}return ans;}
};
 其实这道题最最重要的是回溯思想!!
  • .  -. - 力扣(LeetCode)总结了回溯问题类型,带你搞懂回溯算法(大量例题)
  • 看这个题解就可以

本题over

221. 最大正方形

思想:动态规划

我们可以使用动态规划来解决这个问题。以

假设我们有一个二维矩阵 matrix,其中每个元素是 '0' 或 '1'。我们定义一个额外的二维数组 dp 来存储在以当前位置为右下角的情况下的最大正方形边长。

  1. 首先,将 dp 数组初始化为与原始矩阵相同大小,类型为整数。将第一行和第一列直接复制为原始矩阵的值(因为在边界上无法形成正方形)。

  2. 对于其余位置 (i, j),如果 matrix[i][j] 是 '1',则考虑它左侧、上方和左上方三个位置的 dp 值,取它们的最小值并加 1,dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

  3. 在更新 dp 的过程中,记录下出现的最大边长值,即可得到最大正方形的边长。

  4. 最后,返回最大正方形的面积,即边长的平方。

这样,通过动态规划算法,我们可以高效地找到给定矩阵中的最大正方形的边长。

dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1。
如图,当dp[i][j] 来存储在以当前位置[i][j]为右下角的情况下的最大正方形边长时,
dp的值就与上[i-1][j] 左[i][j-1] 左上[i-1][j-1]三个位置的dp相关。看图可以发现与他们最小值相关。
为什么要加1,因为当前位置计算的话,可定是1,可以构成一个小正方形
图解 

代码如下:一定要分清行列
class Solution {
public:int maximalSquare(vector<vector<char>>& matrix) {int n = matrix.size();int m = matrix[0].size();if (m == 0 || n == 0)return 0;int max_len = 0;vector<vector<int>> dp(n, vector<int>(m));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (matrix[i][j] == '1') {if (i == 0 || j == 0) {//第一行第一列dp值=matrix值dp[i][j] = 1;} else {dp[i][j] = min({dp[i - 1][j], dp[i][j - 1],dp[i - 1][j - 1]}) +1;}max_len = max(max_len, dp[i][j]);}}}return max_len * max_len;}
};

 

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

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

相关文章

【微服务】Nacos配置管理

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;微服务 ⛺️稳中求进&#xff0c;晒太阳 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&am…

DPDK-RCU的简明使用

文章目录 摘要RCU的基本概念DPDK RCU Library的使用其他 摘要 本文主要介绍DPDK中RCU Library的使用。 在使用这个库之前&#xff0c;我们先了解RCU的基本概念。 掌握RCU的基本概念后&#xff0c;便可轻松的使用这个库。 RCU的基本概念 参考&#xff1a;Linux内核同步机制之…

深度学习模型部署-番外-TVM机器学习编译

什么是机器学习编译器/AI编译&#xff1f; 图片来自知乎大佬的文章 机器学习编译是指&#xff1a;将模型从训练形式转变为部署模式 训练模式&#xff1a;使用训练框架定义的模型部署模式&#xff1a;部署所需要的模式&#xff0c;包括模型每个步骤的实现代码&#xff0c;管理资…

什么是代理IP?TikTok运营需要知道的IP知识

对于运营TikTok的从业者来说&#xff0c;IP的重要性自然不言而喻。 在其他条件都正常的情况下&#xff0c;拥有一个稳定&#xff0c;纯净的IP&#xff0c;你的视频起始播放量很可能比别人高出不少&#xff0c;而劣质的IP轻则会限流&#xff0c;重则会封号。那么&#xff0c;如何…

插入排序+希尔排序

目录 插入排序&#xff1a; 希尔排序&#xff1a; 插入排序&#xff1a; 注意这里不要将插入排序和冒泡排序弄混&#xff1a; 插入排序是将数据不断放入前一个有序数列&#xff1a; // 插入排序 void InsertSort(int* a, int n) {for (int j 1; j < n; j){for (int i j;…

Java类的多态作用及解析

多态是面向对象编程中一个重要的特性。简单来说&#xff0c;多态就是指同一个方法在不同的对象上有不同的实现。通过多态&#xff0c;我们可以在运行时根据对象的实际类型来动态地调用相应的方法&#xff0c;从而提高代码的灵活性和可扩展性。 以下是 Java 类中多态的一些作用…

如何用HBuider x网页制作蜡笔小新

目录 下载软件 ​编辑 一.制作蜡笔小新个人介绍界面 二.制作蜡笔小新我的偶像界面 三.制作蜡笔小新我的家乡界面 四.制作蜡笔小新会员注册界面 下载软件 一、HBuilder IDE的下载 HBuilder下载官网地址&#xff1a;http://www.pc6.com/mac/140609.htmlHBuilderX官方电脑版…

【机器学习-07】逻辑回归(Logistic Regression)的介绍和python实现

Logistic Regression 虽然被称为回归&#xff0c;但其实际上是分类模型&#xff0c;并常用于二分类。主要用来表示某件事情发生的可能性&#xff0c;因此因变量的范围在 0 和 1 之间。Logistic Regression 因其简单、可并行化、可解释强深受工业界喜爱。例如&#xff0c;探讨引…

前端静态开发案例-基于H5C3开发的仿照视频网站的前端静态页面-2 样式表部分和效果展示

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载 charset "utf-8"; /* 程序员田宝宝原创版权所有&#xff0c;仿冒必究&#xff0c;该界面是仿照某视频网站官网开发的静态页面 */ …

基于Jenkins + Argo 实现多集群的持续交付

作者&#xff1a;周靖峰&#xff0c;青云科技容器顾问&#xff0c;云原生爱好者&#xff0c;目前专注于 DevOps&#xff0c;云原生领域技术涉及 Kubernetes、KubeSphere、Argo。 前文概述 前面我们已经掌握了如何通过 Jenkins Argo CD 的方式实现单集群的持续交付&#xff0c…

java 继承(下)

前面我们已经说明了什么是继承&#xff1f;继承的好处弊端等&#xff0c;不清楚的可参照链接 java 继承&#xff08;上&#xff09;-CSDN博客 本篇文章主要理解 继承中变量&#xff0c;构造方法&#xff0c;成员方法的访问特点。 1、继承中变量的访问特点 1.1 代码实现 不看…

若依添加页面

背景&#xff1a;我想增加的是一个收支管理的页面 views中直接添加income文件夹&#xff0c;里面放着index.vue 网页的菜单中添加这个页面的菜单

基于springboot的留守儿童爱心网站

技术&#xff1a;springbootmysqlvue 一、系统背景 现代社会&#xff0c;由于经济不断发展&#xff0c;旧物捐赠的数量也在不断的增加&#xff0c;人们对留守儿童爱心信息的需求也越来越高。 以往的留守儿童爱心的管理&#xff0c;一般都是纸质文件来管理留守儿童爱心信息&am…

分布式异步任务框架celery

Celery介绍 github地址&#xff1a;GitHub - celery/celery: Distributed Task Queue (development branch) 文档地址&#xff1a;Celery - Distributed Task Queue — Celery 5.3.6 documentation 1.1 Celery是什么 celery时一个灵活且可靠的处理大量消息的分布式系统&…

Java:设计模式

文章目录 参考简介工厂模式简单工厂模式工厂方法模式抽象工厂模式总结 单例模式预加载懒加载线程安全问题 策略模式 参考 知乎 简介 总体来说设计模式分为三类共23种。 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模…

基于浏览器localStorage作为数据库完成todolsit项目

一、文章内容 TodoList结构搭建HTML代码 TodoList样式编写Css代码 TodoList行为表现JavaScript代码 二、项目展示 项目介绍 Todolist是一个基于B/S模式开发的待办事项软件&#xff0c;主要功能是离线记录用户的待办事项和已经完成的事情&#xff0c;基于htmlcssjs实现&am…

【C++】---string的模拟

【C】---string的模拟 一、string类实现1.string类的构造函数2.swap&#xff08;&#xff09;函数3.拷贝构造函数4.赋值运算符重载5.析构6.迭代器7.operator[ ]8.size9.c_str&#xff08;&#xff09;10.reserve&#xff08;&#xff09;11.resize&#xff08;&#xff09;12.p…

flutter 局部view更新,dialog更新进度,dialog更新

局部更新有好几种方法&#xff0c;本次使用的是 StatefulBuilder 定义 customState去更新对话框内容 import package:flutter/cupertino.dart; import package:flutter/material.dart;class ProgressDialog {final BuildContext context;BuildContext? dialogContext;double _…

【DL经典回顾】激活函数大汇总(四十一)(SinReLU附代码和详细公式)

激活函数大汇总(四十一)(SinReLU附代码和详细公式) 更多激活函数见激活函数大汇总列表 一、引言 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里,激活函数扮演着不可或缺的角色,它们决定着神经元的输出,并且影响着网络的学习能…

8节点空间壳单元Matlab有限元编程 | 曲壳单元 | 模态分析 | 3D壳单元 | 板壳理论| 【源代码+理论文本】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…