代码随想录算法训练营第三十三天(补)

LeetCode/卡码网题目:

  • [322. 零钱兑换](#322. 零钱兑换)
  • [279. 完全平方数](#279. 完全平方数)
  • [139. 单词拆分](#139. 单词拆分)
  • [1920. 基于排列构建数组(每日一题5-6)](#1920. 基于排列构建数组(每日一题5-6))
  • [56. 携带矿石资源(第八期模拟笔试)](#56. 携带矿石资源(第八期模拟笔试))

其他:

今日总结
往期打卡


322. 零钱兑换

跳转:
学习: 代码随想录公开讲解

问题:

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

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

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

思路:

完全背包问题求最小个数,排列或组合都没关系,只需要初始化成大值,剩下的就是价值看成1取最小,和最多物品相反.

复杂度:

  • 时间复杂度: O ( m n ) O(mn) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

java 复制代码
class Solution {
    public int coinChange(int[] coins, int amount) {
        if(amount==0) return 0;
        int[] dp = new int[amount+1];
        Arrays.fill(dp,Integer.MAX_VALUE>>1);
        dp[0] = 0;
        for(int i=0;i<coins.length;i++)
            for(int j=coins[i];j<=amount;j++){
                dp[j] = Math.min(dp[j],dp[j-coins[i]]+1);
            }
        return dp[amount]>10001?-1:dp[amount];
    }
}

279. 完全平方数

跳转:
学习: 代码随想录公开讲解

问题:

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

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

思路:

完全背包问题求最小个数,和上题思路相同.初始化大值,价值看成1取最小.

复杂度:

  • 时间复杂度: O ( m n ) O(mn) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

java 复制代码
class Solution {
    public int numSquares(int n) {
        if (n == 0) return 0;
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE >> 1);
        dp[0] = 0;
        for (int i = 1; i <= Math.sqrt(n); i++) {
            int x = i * i;
            for (int j = x; j <= n; j++) {
                dp[j] = Math.min(dp[j], dp[j -x] + 1);
            }
        }
        return dp[n] > 10001 ? -1 : dp[n];
    }
}

139. 单词拆分

跳转:
学习: 代码随想录公开讲解

问题:

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

注意: 不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

思路:

可以看作完全背包问题,只不过装入需要条件,必须单词符合且前面装过才能装入,而且与排列有关,需要内层循环遍历物品

复杂度:

  • 时间复杂度: O ( m n ) O(mn) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

java 复制代码
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int n = s.length();
        boolean[] dp = new boolean[n+1];
        Arrays.fill(dp,false);
        dp[0] = true;
        for (int i = 1; i <= n; i++) {
            for (String str : wordDict) {
                int x = i-str.length();
                if(x>=0&&dp[x]&&s.substring(x,i).equals(str)){
                    dp[i] = true;
                }
            }
        }
        return dp[n];
    }
}

1920. 基于排列构建数组(每日一题5-6)

跳转:
学习: 灵茶山艾府题解

问题:

给你一个 从 0 开始的排列 nums下标也从 0 开始 )。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans

从 0 开始的排列 nums 是一个由 0nums.length - 10nums.length - 1 也包含在内)的不同整数组成的数组。

思路:

数字搬家,因为每个数字都有位置,所以最后循环一圈肯定能从给当前数搬家到搬家到当前位置,这种循环可能有多组,需要防止重复操作,比如取反后为负数标识为已操作.

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码:

java 复制代码
class Solution {
    public int[] buildArray(int[] nums) {
        for(int i=0;i<nums.length;i++){
            int x = nums[i];
            if(x<0) continue;
            int cur = i;
            while(nums[cur]!=i){
                int nxt = nums[cur];
                nums[cur] = ~nums[nxt];
                cur = nxt;
            }
            nums[cur] = ~x;
        }
        for(int i=0;i<nums.length;i++)
            nums[i] = ~nums[i];
        return nums;
    }
}

56. 携带矿石资源(第八期模拟笔试)

跳转:
学习: 代码随想录公开讲解

问题:

你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类型的矿石资源,每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球,但你的宇航舱有一定的容量限制。

给定一个宇航舱,最大容量为 C。现在有 N 种不同类型的矿石,每种矿石有一个重量 w[i],一个价值 v[i],以及最多 k[i] 个可用。不同类型的矿石在地球上的市场价值不同。你需要计算如何在不超过宇航舱容量的情况下,最大化你所能获取的总价值。

思路:

展开看成01背包求最大价值

复杂度:

  • 时间复杂度: O ( m n k ) O(mnk) O(mnk)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

java 复制代码
import java.util.Scanner;
class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int C = sc.nextInt();
        int N = sc.nextInt();
        int[] w = new int[N];
        int[] v = new int[N];
        int[] nums = new int[N];
        for(int i=0;i<N;i++){
            w[i] = sc.nextInt();
        }
        for(int i=0;i<N;i++){
            v[i] = sc.nextInt();
        }
        for(int i=0;i<N;i++){
            nums[i] = sc.nextInt();
        }
        int[] dp = new int[C+1];
        for(int i=0;i<N;i++){
            for(int k = 0;k<nums[i];k++){
                for(int j=C;j>=w[i];j--){
                    dp[j] = Math.max(dp[j],dp[j-w[i]]+v[i]); 
                }
            }
        }
        System.out.println(dp[C]);
    }
}

总结

练习了完全背包和多重背包问题

往期打卡

代码随想录算法训练营第三十二天

代码随想录算法训练营第三十一天

代码随想录算法训练营第三十天(补)

代码随想录算法训练营第二十九天

代码随想录算法训练营第二十八天

代码随想录算法训练营第二十七天(补)

代码随想录算法训练营第二十六天

代码随想录算法训练营第二十五天

代码随想录算法训练营第二十四天

代码随想录算法训练营第二十三天

代码随想录算法训练营周末四

代码随想录算法训练营第二十二天(补)

代码随想录算法训练营第二十一天

代码随想录算法训练营第二十天

代码随想录算法训练营第十九天

代码随想录算法训练营第十八天

代码随想录算法训练营第十七天

代码随想录算法训练营周末三

代码随想录算法训练营第十六天

代码随想录算法训练营第十五天

代码随想录算法训练营第十四天

代码随想录算法训练营第十三天

代码随想录算法训练营第十二天

代码随想录算法训练营第十一天

代码随想录算法训练营周末二

代码随想录算法训练营第十天

代码随想录算法训练营第九天

代码随想录算法训练营第八天

代码随想录算法训练营第七天

代码随想录算法训练营第六天

代码随想录算法训练营第五天

代码随想录算法训练营周末一

代码随想录算法训练营第四天

代码随想录算法训练营第三天

代码随想录算法训练营第二天

代码随想录算法训练营第一天

*[279. 完全平方数]: LeetCode
*[139. 单词拆分]: LeetCode
*[1920. 基于排列构建数组]: LeetCode
*[56. 携带矿石资源(第八期模拟笔试)]: KamaCoder
*[322. 零钱兑换]: LeetCode

相关推荐
小O的算法实验室17 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
郭涤生18 小时前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿18 小时前
vector
c语言·开发语言·数据结构·c++·算法
Ricky111zzz19 小时前
leetcode学python记录1
python·算法·leetcode·职场和发展
汀、人工智能19 小时前
[特殊字符] 第58课:两个正序数组的中位数
数据结构·算法·数据库架构··数据流·两个正序数组的中位数
liu****19 小时前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯
汀、人工智能19 小时前
[特殊字符] 第79课:分割等和子集
数据结构·算法·数据库架构·位运算·哈希表·分割等和子集
汀、人工智能19 小时前
[特殊字符] 第74课:完全平方数
数据结构·算法·数据库架构·图论·bfs·完全平方数
CoderCodingNo19 小时前
【GESP】C++四、五级练习题 luogu-P1177 【模板】排序
数据结构·c++·算法
Proxy_ZZ019 小时前
从零实现LDPC比特翻转译码器:C语言实战与底层逻辑解析
c语言·算法