动态规划
qq_30926503
工欲善其事,必先利其器。 学习技术,贵“恒”,重“精”,忌“浮”,勿“懒”。 切不可“这山望着那山高”
展开
-
LeetCode 334. 递增的三元子序列
LeetCode 334. 递增的三元子序列给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。数学表达式如下:如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。题解:首先保证:nums[i]>nums[i-1]>nums[i-2]所以需要记录最小位和次小位当小于最小位则替换最小位当小于次小位则替换原创 2020-07-30 11:11:07 · 88 阅读 · 0 评论 -
LeetCode 213. 打家劫舍 II
LeetCode 213. 打家劫舍 II你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。题解:由于是环状,所以第一个房子 和最后一个房子只能选一个偷因此我们只能从这两种情况中选取一个最大值即可。当前最大值原创 2020-07-29 15:33:16 · 107 阅读 · 0 评论 -
LeetCode 174. 地下城游戏
LeetCode 174. 地下城游戏一些恶魔抓住了公主(P)并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为0),要么包含增加骑士健康点数的魔法球(原创 2020-07-29 14:40:58 · 141 阅读 · 0 评论 -
LeetCode 647. 回文子串
LeetCode 647. 回文子串 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。题解:动态规划判断[i,j]是否为回文串,是则true,否则false首先看回文串的定义,要满足i=ji+1=j-1将状态逐渐缩小dp[i][j]=dp[i+1][j-1]意思就是当前的dp[i,j]是否是回文串需要看dp[i+1,j-1]是否是回文串,如果dp[i+1][j-1]都不是回文串,那么原创 2020-07-29 10:45:17 · 110 阅读 · 0 评论 -
LeetCode 面试题 08.02. 迷路的机器人
LeetCode 面试题 08.02. 迷路的机器人设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。网格中的障碍物和空位置分别用 1 和 0 来表示。返回一条可行的路径,路径由经过的网格的行号和列号组成。左上角为 0 行 0 列。如果没有可行的路径,返回空数组。输入: [ [0,0,0], [0,1,0], [0,0,0] ] 输出:[[0,0],[0,原创 2020-07-28 14:42:54 · 251 阅读 · 0 评论 -
LeetCode 岛屿数量
岛屿数量给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。 *岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。 * 此外,你可以假设该网格的四条边均被水包围。题解:典型的dfs深度搜索 遍历每个点,如果为1就使用dfs深度搜索,向四个方向深度查找出同一个岛屿,并将查找过的岛屿1变成0,避免重复查找,沉岛思想public class numIslands { public static int numIslands(c原创 2020-07-27 16:41:35 · 121 阅读 · 0 评论 -
剑指 Offer 53 - II. 0~n-1中缺失的数字
剑指 Offer 53 - II. 0~n-1中缺失的数字一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。 *在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。题解:双指针二分法:分别指向头和尾,如果mid值和下标一致则0~mid没有丢失数字不断缩小查询空间时间复杂度:O(logN)空间复杂度:O(1)public class missingNumber { public static void main(原创 2020-07-27 16:32:23 · 101 阅读 · 0 评论 -
二叉树中的最长交错路径
二叉树中的最长交错路径给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:选择二叉树中 任意 节点和一个方向(左或者右)。 如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。改变前进方向:左变右或者右变左。 重复第二步和第三步,直到你在树中无法继续移动。 交错路径的长度定义为:访问过的节点数目 -1(单个节点的路径长度为 0)。请你返回给定树中最长 交错路径 的长度。题解:动态规划:每遍历到一个节点就需要当前点的最长交错路径定义dp[2]dp原创 2020-07-27 14:49:44 · 380 阅读 · 0 评论 -
单词拆分
单词拆分给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。输入: s = “leetcode”, wordDict = [“leet”, “code”] 输出: true 解释: 返回 true因为 “leetcode” 可以被拆分成 “leet code”。题解动态规划:每次截取i之前的数和hashset的相比,j为0开始截取到i(i=1,i<=s.length())如果截取的存在则为true(i)原创 2020-07-27 14:23:02 · 286 阅读 · 0 评论 -
等差数列划分
等差数列划分如果一个数列至少有三个元素,并且任意两个相邻元素之差相同,则称该数列为等差数列。例如,以下数列为等差数列:1, 3, 5, 7, 97, 7, 7, 73, -1, -5, -9数组 A 包含 N 个数,且索引从0开始。数组 A 的一个子数组划分为数组 (P, Q),P 与 Q 是整数且满足 0<=P<Q<N 。如果满足以下条件,则称子数组(P, Q)为等差数组:元素 A[P], A[p + 1], …, A[Q - 1], A[Q] 是等差的。并且 P +原创 2020-07-27 11:40:28 · 334 阅读 · 0 评论 -
leetcode 第 31 场双周赛和为奇数的子数组数目
和为奇数的子数组数目给你一个整数数组 arr 。请你返回和为 奇数 的子数组数目。由于答案可能会很大,请你将结果对 10^9 + 7 取余后返回。题解:首先明白一点:奇数+偶数=奇数偶数+奇数==奇数那么问题就可以转化成动态规划问题,我们遍历数组的每一个数,如果当前的是奇数,那么我们就要找到多之前有多少个偶数的前缀和,当前如果是偶数,那么就需要找到之前有多少个奇数的前缀和,原因是之前有多少种奇数数组组合,当出现了一个新的能组成奇数的,那么它可以和之前的每一个组合组成一个奇数的子数组原创 2020-07-27 10:04:11 · 207 阅读 · 0 评论 -
矩阵中的最长递增路径
矩阵中的最长递增路径 给定一个整数矩阵,找出最长递增路径的长度。对于每个单元格,你可以往上,下,左,右四个方向移动。你不能在对角线方向上移动或移动到边界外(即不允许环绕)题解: 首先看到这道题,突然想到岛屿那题,每次向着四个方向不断递归只是条件是只递归比当前数大的数,所以使用深度搜索,并且返回搜索中深度最大的一个,然后就就开始巴拉巴拉一顿操作,测试,没问题,上线,超时,一口老血吐出来(意料中)所以就做了优化,每原创 2020-07-26 22:53:45 · 403 阅读 · 0 评论 -
leetcode 第199场周赛第二题 灯泡开关 IV
leetcode 第199场周赛第二题 灯泡开关 IV房间中有 n 个灯泡,编号从 0 到 n-1 ,自左向右排成一行。最开始的时候,所有的灯泡都是 关 着的。请你设法使得灯泡的开关状态和 target 描述的状态一致,其中 target[i] 等于 1 第 i 个灯泡是开着的,等于 0 意味着第 i 个灯是关着的。有一个开关可以用于翻转灯泡的状态,翻转操作定义如下:选择当前配置下的任意一个灯泡(下标为 i )翻转下标从 i 到 n-1 的每个灯泡翻转时,如果灯泡的状态为 0 就变为 1,为 1原创 2020-07-26 19:17:23 · 434 阅读 · 0 评论 -
可获得的最大点数
可获得的最大点数几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。你的点数就是你拿到手中的所有卡牌的点数之和。给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。题解:滑动窗口:由题可知,首先想到每次拿开头或者结尾,选择到最大的点数,就有点头疼了 因为不知道拿开头或者结尾,每次拿的地方不固定,那我们就找一个固定的, 固定的就是剩下的长度一定是len-k原创 2020-07-25 13:50:59 · 206 阅读 · 0 评论 -
礼物的最大价值
礼物的最大价值在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?题解:动态规划:题目中说只能向右和向下移动,所以分为三种情况一、处于上边界二、处于左边界三、处于起点处四、无边界情况分解为子问题,当前礼物的最大值为上一步礼物的最大值加上当前的礼物价值所以需要找到上一步的最大值max(grid[i][原创 2020-07-24 17:58:54 · 116 阅读 · 0 评论 -
比特位计数
比特位计数给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。题解:这种题如果不加限制的话可以选择移位&1的方式计算1的个数但是要求是在O(N)的时间复杂度下完成就需要脑筋急转弯啦0000 ---------> 00001 ---------> 1 ——————0000&0001=0000+10010 ---------> 1 ——————0001&0010原创 2020-07-24 17:36:28 · 291 阅读 · 0 评论 -
零钱兑换
零钱兑换给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。题解:采用自下而上的方式,这样在每次计算F(i)之前我们已经知道F(0)~F(i-1)即可满足将问题分解成子问题,当前问题等于之前问题+当前问题规模例如:coins = [1, 2, 5], amount = 11F(1)=min(F(1−1),F(1−2),F(1−5))+1=1F(2)=min(F(2-1),F(2-2)原创 2020-07-24 16:50:25 · 90 阅读 · 0 评论 -
最大正方形
最大正方形在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。题解:动态规划:使用dp[i][j]代表以i,j为右下角只包含1的正方形首先需要考虑几点一、当前的dp[i][j]的值和和(i-1,j)(i,j-1),(i-1,j-1)有关,如果当前(i,j)为1那么需要考虑这三个位置的最小值加上当前的1,在取最小值时确保是正方形 状态转移方程:dp(i,j)=min(dp(i−1,j),dp(i−1,j−1),dp(i,j−1))+1二、我们每次取当原创 2020-07-24 14:19:50 · 122 阅读 · 0 评论 -
摆动序列
摆动序列如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不原创 2020-07-24 11:26:54 · 860 阅读 · 0 评论 -
连续的子数组和
连续的子数组和给定一个包含 非负数 的数组和一个目标 整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,且总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。题解:求取区间和sum(j)-sum(i)(sum为前缀和数组)既求取区间和(sum[j]-sum[i])%k==0即是求解sum[j]%k=sum[i]%kpublic class checkSubarraySum { public static boolean checkSubarraySum原创 2020-07-23 19:55:28 · 122 阅读 · 0 评论 -
矩阵最小路径和
矩阵最小路径和给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。题解:这是一个动态规划类问题,定义状态dp,dp[i][j]表示的是走到矩阵m-1,n-1处的最小路径要求只能向下和向右走,那么说明当前单元格只能从上单元格(i-1,j)和左单元格(i,j-1)移动到当前单元格,其他的只需要考虑是否边界即可。状态转移方程分为四种情况:一、边界i!=0,j!=0 即可从上单元格和左单元格移动到当前单元格 dp[i][j]=min(dp[i-1]原创 2020-07-23 11:10:47 · 362 阅读 · 0 评论