完全和零一背包

  1. 完全平方数(完全背包)

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12

输出:3

解释:12 = 4 + 4 + 4

public int numSquares(int n) {

int\[\] dp = new intn + 1;

dp0 = 0; // 初始化

for(int j = 1;j<=n;j++)

dpj = Integer.MAX_VALUE;

int m = (int)Math.sqrt(n);

for (int i = 1; i <= m; i++) // 枚举每个数

{

for (int j = i*i; j <= n; j++) // ⽤⼩于 i 的完全平⽅数划分区间

dpj = Math.min(dpj, dpj- i \* i + 1); // 拿到所有划分区间内的

}

// 返回结果

return dpn;

}

  1. 零钱兑换(完全背包)

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1(题目给暗示了) 。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = 1, 2, 5, amount = 11

输出:3

解释:11 = 5 + 5 + 1

public int coinChange(int\[\] coins, int amount) {

int n = coins.length, INF = 0x3f3f3f3f;

int\[\] dp = new intamount + 1;

for (int j = 1; j <= amount; j++)

dpj = INF;

for (int i = 1; i <= n; i++)

for (int j =coinsi - 1; j <= amount; j++)

dpj = Math.min(dpj, dpj - coins\[i - 1] + 1);

return dpamount >= INF ? -1 : dpamount;

}

  1. 分隔等和子集(01背包)

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

示例 1:

输入:nums = 1,5,11,5

输出:true

解释:数组可以分割成 1, 5, 511

public boolean canPartition(int\[\] nums) {

int n = nums.length;

int sum = 0;

for (int x : nums)

sum += x;

if (sum % 2 == 1 || sum < 0)

return false;

int target = sum / 2;

boolean\[\] dp = new booleantarget + 1; // 建表

dp0 = true;

for (int i = 1; i <= n; i++) {

for (int j = target; j >= numsi - 1; j--) {

dpj = dpj || dpj - nums\[i - 1];

}

}

return dptarget;

}

  1. 单词拆分

输入: s = "leetcode", wordDict = "leet", "code"

输出: true

解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

public boolean wordBreak(String s, List<String> wordDict) {

int n = s.length();

boolean\[\]dp = new booleann+1;

dp0 = true;

s = " "+s;

for(int i = 1;i<=n;i++){

for(int j = 0;j<i;j++){

if(dpj&&wordDict.contains(s.substring(j+1,i+1))){

dpi = true;

}

}

}

return dpn;

}

  1. 乘积最大子数组

输入: nums = 2,3,-2,4

输出: 6

解释: 子数组 2,3 有最大乘积 6。

public int maxProduct(int\[\] nums) {

int n = nums.length;

int\[\] f = new intn + 1;

int\[\] g = new intn + 1;

f0 = g0 = 1;

int ret = Integer.MIN_VALUE;

for (int i = 1; i <= n; i++) {

int x = numsi - 1, y = fi - 1 * numsi - 1, z = gi - 1 * numsi - 1;

fi = Math.max(x, Math.max(y, z));

gi = Math.min(x, Math.min(y, z));

ret = Math.max(ret, fi);

}

return ret;

}

20.编辑距离

如果是增操作,即是word1要增加一个字符才跟word2一样, 说明word1的0..i跟word2的0..j - 1是一样的 , dpij = dpij - 1 + 1 如果是删操作,也是word1要删除一个字符才跟word2一样,说明word1的0..i - 1跟word2的0..j是一样的, dpij = dpi - 1j + 1 替换的话就也好理解 , 说明word1的0..i - 1跟word2的0..j - 1是一样的

增,dpij = dpij - 1 + 1

删,dpij = dpi - 1j + 1

改,dpij = dpi - 1j - 1 + 1

输入:word1 = "horse", word2 = "ros"

输出:3

解释:

horse -> rorse (将 'h' 替换为 'r')

rorse -> rose (删除 'r')

rose -> ros (删除 'e')

public int minDistance(String word1, String word2) {

int m = word1.length();

int n = word2.length();

int\[\]\[\]dp = new intm+1n+1;

for(int i = 0;i<=m;i++)

dpi0 = i;

for(int j = 0;j<=n;j++)

dp0j = j;

for(int i = 1;i<=m;i++){

for(int j = 1;j<=n;j++){

dpij = Math.min(dpi-1j,Math.min(dpi-1j-1,dpij-1))+1;

if(word1.charAt(i-1)==word2.charAt(j-1)){

dpij = Math.min(dpij,dpi-1j-1);

}

}

}

return dpmn;

}

  1. 最长有效括号
相关推荐
星轨初途26 分钟前
LeetCode 热题 100——day11 滑动窗口最大值
数据结构·c++·算法·leetcode·职场和发展
gbase_lmax1 小时前
深度递归与广度递归(DFS,BFS)实现
算法·深度优先·宽度优先
西柚研究生1234562 小时前
论文分析15:跨层特征交互的多尺度无人机小目标检测算法
人工智能·算法·目标检测
rannn_1119 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
数模竞赛Paid answer9 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
不会代码的小猴10 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
营养充电站10 小时前
VS Code Git 工作树:解锁多分支并行开发的高效体验
leetcode·决策树·逻辑回归·散列表·模拟退火算法
AI备案指南-满满11 小时前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案
江畔柳前堤11 小时前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
一只旭宝11 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法