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

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

相关推荐
.YM.Z1 小时前
C语言——操作符
c语言·开发语言·算法
江畔柳前堤1 小时前
信息论12:从信息增益到信息增益比——决策树中的惩罚机制与应用
运维·深度学习·算法·决策树·机器学习·计算机视觉·docker
apcipot_rain2 小时前
【计算机网络 第8版】谢希仁编著 第四章网络层 地址类题型总结
数据结构·算法
Matlab程序猿小助手2 小时前
【MATLAB源码-第277期】基于matlab的AF中继系统仿真,AF和直传误码率对比、不同中继位置误码率对比、信道容量、中继功率分配以及终端概率。
开发语言·网络·算法·matlab·kmeans·simulink
Codeking__2 小时前
滑动窗口——长度最小子数组
算法
J先生x3 小时前
【IP101】图像分割技术全解析:从传统算法到深度学习的进阶之路
图像处理·人工智能·深度学习·学习·算法·计算机视觉
NON-JUDGMENTAL3 小时前
第2章 算法分析基础
java·数据结构·算法
wen__xvn3 小时前
每日一题洛谷P1025 [NOIP 2001 提高组] 数的划分c++
数据结构·c++·算法
朱剑君4 小时前
排序算法——桶排序
算法·排序算法