算法刷题之动态规划
杰明学编程
这个作者很懒,什么都没留下…
展开
-
9.29西山居笔试
1.背包问题题目描述:有一个冒险者,靠着好运气找到了一个大宝藏,宝藏里面珍宝无数,它们价值各异且重量不同。冒险者身边只带了一个旅行袋,容量有限,那么他到底拿那些宝物可以收益多少?输入:5,50,[5,3,20,35,28],[20,70,200,400,320]输出:520说明:参数一[5]表示总共有5个宝物,参数二[50]是背包的容量,参数三[5,3,20,35,28]是5个宝藏物各自的重量,参数四[20,70,200,400,320]是五个宝物各自的价值,输出[520]是在最优选择下能达原创 2020-09-30 19:03:21 · 1472 阅读 · 1 评论 -
139. 单词拆分
题目:给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。方法一:动态规划函数代码:class Solution {public: bool wordBreak(string s, vector<string>& wordDict) { auto wordDictSet = unordered_se原创 2020-09-08 17:47:06 · 93 阅读 · 0 评论 -
377. 组合总和 Ⅳ
题目:给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。题解思路:方法一:一维动态规划函数代码:class Solution {public: int combinationSum4(vector<int>& nums, int target) { int n=nums.size(); vector<unsigned long long> dp(target+1,0); dp原创 2020-09-08 11:08:20 · 90 阅读 · 0 评论 -
516. 最长回文子序列
题目:给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。题解思路:方法一:动态规划函数代码:class Solution {public: int longestPalindromeSubseq(string s) { int n=s.size(); vector<vector<int>>dp(n,vector<int>(n,0)); for(原创 2020-09-08 01:40:17 · 77 阅读 · 0 评论 -
1143. 最长公共子序列
题目:给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。若这两个字符串没有公共子序列,则返回 0。题解思路:方法一:动态规划函数代码:class Solutio原创 2020-09-08 01:40:22 · 81 阅读 · 0 评论 -
264. 丑数 II
题目:编写一个程序,找出第 n 个丑数。丑数就是质因数只包含 2, 3, 5 的正整数。题解思路:方法一:动态规划函数代码:class Solution {public: int nthUglyNumber(int n) { vector<int>dp(n,0); dp[0]=1; int a=0,b=0,c=0; for(int i=1;i<n;i++) { dp[i]=m原创 2020-09-08 01:40:12 · 87 阅读 · 0 评论 -
300. 最长上升子序列
题目:给定一个无序的整数数组,找到其中最长上升子序列的长度。题解思路:方法一:动态规划函数代码:class Solution {public: int lengthOfLIS(vector<int>& nums) { int n=nums.size(); vector<int>dp(n+1,1); int res=0; for(int i=0;i<n;i++) {原创 2020-09-07 04:34:57 · 69 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和
题目: 同力扣53 最大子序和输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。题解思路:方法一:动态规划注意res=dp[0]=nums[0];函数代码:class Solution {public: int maxSubArray(vector<int>& nums) { int n=nums.size(); vector<int> dp(n,0);原创 2020-09-07 04:06:31 · 88 阅读 · 0 评论 -
518. 零钱兑换 II
题目:给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。题解思路:方法一:二维dp+完全背包函数代码:class Solution {public: int change(int amount, vector<int>& coins) { int n=coins.size(); int sum=0; for(int i=0;i<n;i++) {原创 2020-09-07 03:43:23 · 92 阅读 · 0 评论 -
494. 目标和
题目:给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。返回可以使最终数组和为目标数 S 的所有添加符号的方法数。题解思路:方法一:一维度dp+完全背包函数代码:class Solution {public: int findTargetSumWays(vector<int>& nums, int S) { int n=num原创 2020-09-07 03:17:07 · 94 阅读 · 0 评论 -
416. 分割等和子集
题目:给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。注意:每个数组中的元素不会超过 100数组的大小不会超过 200题解思路:方法一:二维动态规划+0-1背包函数代码:class Solution {public: bool canPartition(vector<int>& nums) { int n=nums.size(); int sum=0; for(int原创 2020-09-07 02:31:07 · 78 阅读 · 0 评论 -
343. 整数拆分
题目:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。题解思路:方法一:数学分割法思路:1.判断数字n是否小于等于3,若是,返回n-1;否则把整数n除以3整数部分为a,余数部分为b,在利用指数部分计算。3.如果b为0,则数字最大为pow(3,a);b为1,最大数字为pow(3,a-1)*4;b为2时,最大数字为pow(3,a)*2.函数代码:class Solution {public: int integerBreak(i原创 2020-09-01 15:16:29 · 194 阅读 · 0 评论 -
213. 打家劫舍 II
题目:你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。题解思路:方法一:类似于斐波那契解法1.数组元素长度为n2.讨论是否到最后抢劫数组元素末尾,如果抢劫数组元素末尾nums[n-1],就只能从1开始抢劫;如果不原创 2020-09-06 20:35:28 · 89 阅读 · 0 评论 -
121. 买卖股票的最佳时机
题目:给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。函数代码:class Solution {public: int maxProfit(vector<int>& prices) { int n=prices.size(); int profit; int minpric原创 2020-09-06 17:48:24 · 74 阅读 · 0 评论 -
198. 打家劫舍
题目:你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。题解思路:方法:动态规划1.判断数组长度n的大小,n为0,1,2的情况。函数代码:class Solution {public: int rob(vector<int>&原创 2020-09-06 17:36:24 · 67 阅读 · 0 评论 -
62. 不同路径
题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?函数代码:class Solution {public: int uniquePaths(int m, int n) { vector<vector<int>>dp(m,vector<int>(n,0));原创 2020-09-06 17:20:01 · 74 阅读 · 0 评论 -
279. 完全平方数
题目:给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。函数代码:class Solution {public: int numSquares(int n) { if(n==0) { return 0; } //记得这里初始化要n+1,因为是求最小值,不能初始化为0,初始化为0,输出一直为0,因为0是最小的。原创 2020-09-06 17:10:23 · 80 阅读 · 0 评论 -
120. 三角形最小路径和
题目:给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。题解思路:方法一:二维动态规划,自顶向下1.初始化第一行dp[0][0]=triangle[0][0];2.状态转移方程:当j=0时,dp[i][0]=triangle[i][j]+dp[i-1][j];当j=triangle[i].size()-1时,也就是第i行的最后一个元素时,dp[i][j]=tri原创 2020-09-06 14:14:30 · 80 阅读 · 0 评论 -
64. 最小路径和
题目:给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。题解思路:方法一:二维动态规划函数代码:class Solution {public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(); int n=grid[0].size(); ve原创 2020-09-06 13:17:44 · 62 阅读 · 0 评论 -
322. 零钱兑换
题目:给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。题解思路:方法一:动态规划函数代码:class Solution {public: int coinChange(vector<int>& coins, int amount) { vector<int>dp(amount+1,amount+1); dp[原创 2020-08-18 08:27:16 · 69 阅读 · 0 评论