LeetCode——动态规划篇(二)

2023-11-13

 刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com 

目录

343. 整数拆分 - 力扣(LeetCode)

96. 不同的二叉搜索树 - 力扣(LeetCode)

416. 分割等和子集 - 力扣(LeetCode)

1049. 最后一块石头的重量 II - 力扣(LeetCode)


 

343. 整数拆分 - 力扣(LeetCode)

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
import java.util.Scanner;

/**
 * @author light
 * @Description 整数拆分
 * @create 2023-09-14 18:19
 */
public class IntegerBreakTest {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		System.out.println(integerBreak(n));
	}
	public static int integerBreak(int n) {
		 //dp[i] 为正整数 i 拆分后的结果的最大乘积
        int[] dp = new int[n+1];
        dp[2] = 1;
        for(int i = 3; i <= n; i++) {
            for(int j = 1; j <= i-j; j++) {
                // 这里的 j 其实最大值为 i-j,再大只不过是重复而已,
                //并且,在本题中,我们分析 dp[0], dp[1]都是无意义的,
                //j 最大到 i-j,就不会用到 dp[0]与dp[1]
                dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
                // j * (i - j) 是单纯的把整数 i 拆分为两个数 也就是 i,i-j ,再相乘
                //而j * dp[i - j]是将 i 拆分成两个以及两个以上的个数,再相乘。
            }
        }
        return dp[n];
	}
}

96. 不同的二叉搜索树 - 力扣(LeetCode)

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。


/**
 * @author light
 * @Description 不同的二叉搜索树
 *
 * @create 2023-09-14 18:49
 */
public class NumTreesTest {
	public int numTrees(int n) {
		//1 确认dp数组及其含义:dp[i]:输入【i】,共有dp[i]种不同的二叉搜索树
		//也可以理解是i个不同元素节点组成的二叉搜索树的个数为dp[i] ,都是一样的。
		//dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
		//j相当于是头结点的元素,从1遍历到i为止。
		int[] dp=new int[n+1];
		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];
	}
}

416. 分割等和子集 - 力扣(LeetCode)

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
import java.util.Scanner;

/**
 * @author light
 * @Description 分割等和子集
 * @create 2023-09-15 9:23
 */
public class CanPartitionTest {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n= input.nextInt();
		int[] num=new int[n];
		for (int i = 0; i < n; i++) {
			num[i]=input.nextInt();
		}
		System.out.println(canPartition(num));
	}
	public static boolean canPartition(int[] nums) {
		// 不能均分,直接返回false
		int sum = 0;
		for (int n : nums) {
			sum += n;
		}
		if (sum % 2 != 0) {
			return false;
		}
		// 能均分,计算平均分
		int score = sum / 2;
		/**
		 * 回溯
		 * 	//标记数组
		 * 	boolean[] flag = new boolean[nums.length];
		 * Arrays.fill(flag, false);
		 * return helper(nums, flag, 0, score, 0);
		 *
		 */
		/**
		 * 动规:1.二维数组
		 * dp[i][j]:从[0-i]中任选,装进背包容量为j的背包,所获得的最大价值为dp[i][j]
		 *
		  int[][] dp=new int[nums.length][score+1];
		//初始化看背包容量:
		// 当背包容量为零时,背包中放不进任何一个物品--->初始化为零
		// 看物品:已经放入物品一个,若背包容量大于物品重量,背包中是物品的价值,否则--->0
		for (int i = 0; i < nums.length; i++) {
			dp[i][0]=0;
		}
		for (int i = 0; i <=score; i++) {
			if(i<nums[0]){
				dp[0][i]=0;
			}else{
				dp[0][i]=nums[0];
			}
		}
		for (int i = 1; i < nums.length; i++) {
			for (int j = 1; j <=score; j++) {
				if(j>=nums[i]){
					dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
				}else {
					dp[i][j]=dp[i-1][j];
				}
			}
		}
		if(dp[nums.length-1][score]==score){
			return true;
		}else {
			return false;
		}

		 */

		/**
		 *  动规:2.滚动数组
		 *  dp[j]:背包容量为j的背包,所能容纳的最大价值为dp[j]
		 */
		int[] dp=new int[score+1];
		dp[0]=0;
		for (int i = 0; i < nums.length; i++) {
			for (int j = score; j>=nums[i] ; j--) {
				dp[j]=Math.max(dp[j],dp[j-nums[i]]+nums[i]);
			}
		}
		if(dp[score]==score){
			return true;
		}
		return false;


	}
	//回溯
	private  static  boolean helper(int[] nums,  boolean[] flag, int curnum, int score, int pos) {
		// 每一轮的终止条件:这一轮满足条件了,可以下一轮了
		if (curnum == score) {
			return true;
		}
		// 从头开始新的一轮,子集的累计和
		for (int i = pos; i < nums.length; i++) {
			if (flag[i]) {
				continue;
			}
			flag[i] = true;
			if(helper(nums, flag, curnum + nums[i], score, i + 1)){
				return true;
			}
			flag[i] = false;
		}
		return false;
	}
}

1049. 最后一块石头的重量 II - 力扣(LeetCode)

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

  • 如果 x == y,那么两块石头都会被完全粉碎;
  • 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x

最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0

输入:stones = [2,7,4,1,8,1]
输出:1
解释:
组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。

import java.util.Scanner;

/**
 * @author light
 * @Description 最后一块石头的重量
 *
 *
 * (思路:尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。
 * @create 2023-09-21 15:03
 */
public class LastStoneWeightIITest {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n= input.nextInt();
		int[] stones=new int[n];
		for (int i = 0; i < n; i++) {
			stones[i]=input.nextInt();
		}
		System.out.println(lastStoneWeightII(stones));
	}
	public static int lastStoneWeightII(int[] stones) {
		int sum=0;
		for (int n : stones) {
			sum += n;
		}
		int target = sum / 2;
		//dp[i][j]含义:任选[0-i] 个石头,装入容量为j的背包中,背包的最大重量为dp[i][j]
		int[][] dp=new int[stones.length][target+1];
		for (int i = 0; i < stones.length; i++) {
			dp[i][0]=0;
		}
		for (int i = 0; i <=target; i++) {
			if(i>=stones[0]){
				dp[0][i]=stones[0];
			}
		}
		for (int i = 1; i < stones.length; i++) {
			for (int j = 1; j <=target; j++) {
				if(j>=stones[i]){
					dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-stones[i]]+stones[i]);
				}else {
					dp[i][j]=dp[i-1][j];
				}

			}
		}
		return sum-dp[stones.length-1][target]-dp[stones.length-1][target];
	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode——动态规划篇(二) 的相关文章

  • 使用 Intellij Idea 和 gradle 在应用程序引擎上调试 localhost

    我正在使用 IntelliJ 社区添加并使用 Gradle 构建应用程序引擎标准环境应用程序 在迁移到 IntelliJ 和端点框架之前 我使用的是 Android Studio 我无法调试我的本地主机 我添加了 jvmFlags 如下所述
  • 按下按钮并在java中的新窗口中打开文件

    我创建了一个 JFrame 并放置了一个文本字段和按钮 在文本字段中我放置了从文本文件读取的名称 我知道我想单击按钮并打开一个已知窗口 我想在其中放置名称 其他信息来自同一个文件 这是我的代码 这是我的主框架 package Fronten
  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • 如何在 JavaFX 中连接可观察列表?

    我所说的串联是指获得一个新列表 该列表侦听所有串联部分的更改 方法的目的是什么FXCollections concat ObservableList
  • Thymeleaf 3 Spring 5 映射加载字符串而不是 HTML

    我正在尝试将 Spring 5 和 Thymeleaf 3 一起配置 我正在 Eclipse 上工作 我使用 全新安装 构建并使用 springboot run 运行应用程序 我已经设置了一个控制器和几个模板 但 Thymeleaf 似乎找
  • 如何在 Java 中向时间戳添加/减去时区偏移量?

    我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多 但我仍然无法解决我面临的问题 假设我得到了格式化的Timestamp在格林威治标准时间 UTC 我的服务器位于某处 假设它设置为Asia Calcu
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja
  • 提供节点名或服务名,或未知 Java

    最近我尝试运行我的 Java 项目 每当我运行它并将其打开到我得到的服务器地址时 Unable to determine host name java net UnknownHostException Caused by java net
  • 提高 PostgreSQL 1 亿数据左连接查询性能

    我在用Postgresql 9 2 version Windows 7 64 bit RAM 6GB 这是一个Java企业项目 我必须在我的页面中显示订单相关信息 有三个表通过左连接连接在一起 Tables TV HD 389772 行 T
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • 如何区分从 Saxon XPathSelector 返回的属性节点和元素节点

    给定 XML
  • 在 Spring 上下文中查找方法级自定义注释

    我想知道的是 所有的类 方法Spring http en wikipedia org wiki Spring Framework注释为 Versioned的bean 我创建了自定义注释 Target ElementType METHOD E
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • java 中的蓝牙 (J2SE)

    我是蓝牙新手 这就是我想做的事情 我想获取连接到我的电脑上的蓝牙的设备信息并将该信息写入文件中 我应该使用哪个 api 以及如何实现 我遇到了 bluecove 但经过几次搜索 我发现 bluecove 不能在 64 位电脑上运行 我现在应
  • Android View Canvas onDraw 未执行

    我目前正在开发一个自定义视图 它在画布上绘制一些图块 这些图块是从多个文件加载的 并将在需要时加载 它们将由 AsyncTask 加载 如果它们已经加载 它们只会被绘制在画布上 这工作正常 如果加载了这些图片 AsyncTask 就会触发v
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • Java 11 - 将 Spring @PostConstruct 替换为 afterPropertiesSet 或使用 initMethod

    我正在使用 spring 应用程序 有时会使用 PostConstruct用于代码和测试中的设置 看来注释将被排除在外Java 11 https www baeldung com spring postconstruct predestro
  • java'assert'和'if(){}else exit;'之间的区别

    java和java有什么区别assert and if else exit 我可以用吗if else exit代替assert 也许有点谷歌 您应该记住的主要事情是 if else 语句应该用于程序流程控制 而assert 关键字应该仅用于
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • PHP定时访问api解决方案【已测试通过】

    背景介绍 今天打算做一个数据统计功能 由于数据结构复杂 无法通过存储过程来完成 所以只能开发PHP功能 定时调用该功能以完成数据统计 方案1 创建Windows计划任务 定时执行 bat批处理文件 具体实施方法 先创建一个 bat文件 例如
  • vue2 升级到 vue3 router 动态授权路由 异步加载报错 TypeError: Cannot read properties of undefined (reading ‘apply‘)

    使用 resolve gt require views item component resolve 会报错 TypeError Cannot read properties of undefined reading apply 我的解决历
  • 替换字符串中指定的字符串

    例如下面的例子 有时需要把某个字符串中的部分字符替换成另一个字符 可以使用std string 自带的函数replace replace第一个参数为起点 第二个为替换的长度 第三个为替换为的内容 for auto inventoryStat
  • 跟我学Spring Cloud(2020.0.0-M6版)-01-服务注册与服务发现-Eureka Server

    目录 1 所需要版本 2 创建基于web的Maven项目 SpringCloud 的服务注册中心 3 检查IntelliJ IDEA 的环境配置 4 检查java verison配置 5 检查Edit Configurations配置 6
  • 区块链技术基本概念

    链客 专为开发者而生 有问必答 此文章来自链客区块链技术问答社区 未经允许拒绝转载 区块链技术根本概念 了解这些名词是一个不错的开端 公钥加密系统 Alice有一把公钥和一把私钥 她可以用她的私钥创建数字签名 而Bob可以用她的公钥来验证这
  • 自定义 swap 函数

    背景 STL 中提供了 swap 算法 用于交换两个对象的值 其一般实现方法如下 namespace std template
  • c语言缩进用tab还是空格,程序员编码首行缩进使用Tab键好还是空格好?

    本文转载自CocoaChina 每个程序员都有自己喜欢的编码风格以及编码习惯 那么 问题来了 一个很常用也很简单的问题 让程序员分为两派 编程时 到时是使用Tab按键来进行首行缩进好呢还是敲空格按键好呢 少侠 别急 带老夫给你慢慢分析 Ta
  • Git入门与使用 (二) Git相关命令的介绍与使用

    文章目录 一 前言 二 理解Git的工作区 暂存区 本地仓库和远程仓库 三 Git相关命令的介绍与使用 1 初始化Git仓库 2 设置签名 2 1 设置仓库 项目级别的签名 2 2 设置系统用户级别的签名 3 查看Git仓库的状态 4 向暂
  • [转]Windows下安全权限设置详解

    一 Windows下安全权限设置详解 简 介 随着动网论坛的广泛应用和动网上传漏洞的被发现以及SQL注入式攻击越来越多的被使用 WEBSHELL让防火墙形同虚设 一台即使打了所有微软补丁 只让80端口对外开放的WEB服务器也逃不过被黑的命运
  • 刷脸庞大的交易市场从而也带来新的商机

    现在我们外出买东西付款 已经有了非常便捷的扫码支付功能 这个功能不仅是年轻人喜欢使用 就连中老年人也跟上的时代的步伐 许多超市 便利店已经菜市场 都能够看到二维码的身影 但是随着时代不断地进步 扫码付款这一新兴方式 接二连三地被曝出许多风险
  • Unity自动滚动字幕的实现

    Unity自动滚动字幕的实现 首先按照图片里的进行创建 然后用代码获取Scrollbar 在将Value值一直变为1 using System Collections using System Collections Generic usi
  • Jupyter程序安装和使用指南【操作示例】

    Jupyter Notebook 简称Jupyter 是一个交互式编辑器 它支持运行40多种编程语言 便于创建和共享文档 Jupyter本质上是一个Web应用程序 与其他编辑器相比 它具有小巧 灵活 支持实时代码 方便图表展示等优点 下面分
  • ECCV 2020 Representation Learning on Visual-Symbolic Graphs for Video Understanding

    动机 自然视频中的事件通常产生于演员和目标之间的时空交互 并且涉及多个共同发生的活动和目标类 因此 需要开发能够对时空视觉和语义上下文进行有效建模的算法 捕捉这种上下文的一种方法是使用基于图的建模 它在计算机视觉中有着丰富的历史 传统的基于
  • qt day3

  • java自动装配_Spring中自动装配的4种方式

    Spring容器可以在不使用和元素的情况下自动装配相互协作的bean之间的关系 助于减少编写一个大的基于Spring的应用程序的XML配置的数量使用元素的autowire属性为一个bean定义指定自动装配模式 在Spring中 我们有4种方
  • 计算机网络期末总结复习(全)

    文章目录 第一章 概述 1 1 计算机网络在信息时代的作用 我国互联网发展状况 1 2 因特网概述 1 网络 互连网 互联网 和因特网 2 因特网发展的三个阶段 3 因特网的标准化工作 4 因特网的组成 补充
  • 78页PPT全面揭示互联网与传统行业的融合与碰撞

    正如报告的主题 融合与碰撞 移动互联网和传统行业正在融合与碰撞之间进行行业重塑 纵观教育行业 现阶段已经有四种运营模式逐渐成熟 但仍存在自身问题和很多外部矛盾 找准发展趋势意义重大 一起来看看水深火热的TMT产业发展趋势吧
  • 【前端demo】背景渐变动画

    文章目录 效果 过程 代码 html css 其他demo 效果 效果预览 https codepen io karshey pen OJrXZwQ 过程 注意 直接在body上加height 100 可能也会出现height为0的情况 这
  • docker修改服务器参数怎么办,Docker(32)- 如何修改 docker 容器的启动参数

    如果你还想从头学起 Docker 可以看看这个系列的文章哦 前言 有时候创建容器时忘了添加 restart 参数 导致 Docker 服务重启后 容器不会自动启动 每次都需要手动启动 很不方便 那现在如何针对已创建的容器修改 restart
  • LeetCode——动态规划篇(二)

    刷题顺序及思路来源于代码随想录 网站地址 https programmercarl com 目录 343 整数拆分 力扣 LeetCode 96 不同的二叉搜索树 力扣 LeetCode 416 分割等和子集 力扣 LeetCode 104