当前位置: 首页 > news >正文

老司机网站做暖暖哪个平台可以免费推广

老司机网站做暖暖,哪个平台可以免费推广,做软件项目需不需要有网站,青海网站建设哪家强给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图&#xf…

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 
输入:height = [4,2,0,3,2,5]
输出:9

自己写的

 public class Solution

 {

     public int Trap(int[] height)

     {

         int[] Theleft=new int[height.Length];

         int[] Therightside=new int[height.Length];

         int[] res=new int[height.Length];

         int result = 0;

         int left=Theleft[0];

         int right = Therightside[Therightside.Length - 1];

         for (int i = 0; i < height.Length; i++)

         {

             if (left <= height[i])

             {

                 Theleft[i] = 0;

                 left = height[i];

             }

             else

             {

                 Theleft[i] = left - height[i] ;

                 

             }

         }

         for (int i = height.Length-1; i >= 0; i--)

         {

             if (right <= height[i])

             {

                 Therightside[i] = 0;

                 right = height[i];

             }

             else

             {

                 Therightside[i] = right - height[i];

                 

             }

         }

         for (int i = 0; i < height.Length; i++)

         {

             res[i]= Math.Min(Theleft[i], Therightside[i]);

         }

         for (int i = 0; i < res.Length; i++)

         {

             result=result + res[i];

         }

         return result;

     }

 }

空间复杂度比较高 和官方的第一个题解一样

方法一:动态规划
对于下标 i,下雨后水能到达的最大高度等于下标 i 两边的最大高度的最小值,下标 i 处能接的雨水量等于下标 i 处的水能到达的最大高度减去 height[i]。

朴素的做法是对于数组 height 中的每个元素,分别向左和向右扫描并记录左边和右边的最大高度,然后计算每个下标位置能接的雨水量。假设数组 height 的长度为 n,该做法需要对每个下标位置使用 O(n) 的时间向两边扫描并得到最大高度,因此总时间复杂度是 O(n 
2
 )。

上述做法的时间复杂度较高是因为需要对每个下标位置都向两边扫描。如果已经知道每个位置两边的最大高度,则可以在 O(n) 的时间内得到能接的雨水总量。使用动态规划的方法,可以在 O(n) 的时间内预处理得到每个位置两边的最大高度。

创建两个长度为 n 的数组 leftMax 和 rightMax。对于 0≤i<n,leftMax[i] 表示下标 i 及其左边的位置中,height 的最大高度,rightMax[i] 表示下标 i 及其右边的位置中,height 的最大高度。

显然,leftMax[0]=height[0],rightMax[n−1]=height[n−1]。两个数组的其余元素的计算如下:

当 1≤i≤n−1 时,leftMax[i]=max(leftMax[i−1],height[i]);

当 0≤i≤n−2 时,rightMax[i]=max(rightMax[i+1],height[i])。

因此可以正向遍历数组 height 得到数组 leftMax 的每个元素值,反向遍历数组 height 得到数组 rightMax 的每个元素值。

在得到数组 leftMax 和 rightMax 的每个元素值之后,对于 0≤i<n,下标 i 处能接的雨水量等于 min(leftMax[i],rightMax[i])−height[i]。遍历每个下标位置即可得到能接的雨水总量。

 但是官方的双指针更优化

方法三:双指针
动态规划的做法中,需要维护两个数组 leftMax 和 rightMax,因此空间复杂度是 O(n)。是否可以将空间复杂度降到 O(1)?

注意到下标 i 处能接的雨水量由 leftMax[i] 和 rightMax[i] 中的最小值决定。由于数组 leftMax 是从左往右计算,数组 rightMax 是从右往左计算,因此可以使用双指针和两个变量代替两个数组。

维护两个指针 left 和 right,以及两个变量 leftMax 和 rightMax,初始时 left=0,right=n−1,leftMax=0,rightMax=0。指针 left 只会向右移动,指针 right 只会向左移动,在移动指针的过程中维护两个变量 leftMax 和 rightMax 的值。

当两个指针没有相遇时,进行如下操作:

使用 height[left] 和 height[right] 的值更新 leftMax 和 rightMax 的值;

如果 height[left]<height[right],则必有 leftMax<rightMax,下标 left 处能接的雨水量等于 leftMax−height[left],将下标 left 处能接的雨水量加到能接的雨水总量,然后将 left 加 1(即向右移动一位);

如果 height[left]≥height[right],则必有 leftMax≥rightMax,下标 right 处能接的雨水量等于 rightMax−height[right],将下标 right 处能接的雨水量加到能接的雨水总量,然后将 right 减 1(即向左移动一位)。

当两个指针相遇时,即可得到能接的雨水总量。

下面用一个例子 height=[0,1,0,2,1,0,1,3,2,1,2,1] 来帮助读者理解双指针的做法。

 

class Solution {public int trap(int[] height) {int ans = 0;int left = 0, right = height.length - 1;int leftMax = 0, rightMax = 0;while (left < right) {leftMax = Math.max(leftMax, height[left]);rightMax = Math.max(rightMax, height[right]);if (height[left] < height[right]) {ans += leftMax - height[left];++left;} else {ans += rightMax - height[right];--right;}}return ans;}
}

关于动态规划的介绍

动态规划(Dynamic Programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

动态规划经常用于求解具有重叠子问题和最优子结构性质的问题。这里的“重叠子问题”是指在递归算法中反复出现的问题,而“最优子结构”是指问题的最优解包含其子问题的最优解。

动态规划的关键步骤:

  1. 识别子问题:将问题分解为小的子问题,这些子问题往往是原问题的规模较小的版本。

  2. 确定状态:定义问题的解状态,通常用变量表示,例如 dp[i]

  3. 确定状态转移方程:找出状态之间的关系,即当前状态是如何由之前的一个或多个状态推导出来的。

  4. 确定初始状态和边界条件:确定状态转移的起点,即基本情况或边界条件。

  5. 确定求解策略:是自底向上(从最小的子问题开始解决)还是自顶向下(递归地解决)。

  6. 构造最优解:根据子问题的解构造原问题的解。

动态规划的常见应用:

  • 斐波那契数列:计算第n个斐波那契数。
  • 背包问题:在不超过背包容量的前提下,选择物品以最大化价值。
  • 最长公共子序列:找出两个序列的最长公共子序列。
  • 最短路径问题:如贝尔曼-福特算法解决带负权边的最短路径问题。
  • 矩阵链乘问题:计算矩阵乘法的最少操作次数。
  • 编辑距离问题:计算两个字符串之间的最小编辑距离。

示例:斐波那契数列的动态规划解法

斐波那契数列是一个典型的动态规划问题,其递归解法存在大量重复计算。动态规划解法如下:

  1. 状态定义dp[i] 表示斐波那契数列的第 i 个数。
  2. 状态转移方程dp[i] = dp[i-1] + dp[i-2]
  3. 初始状态dp[0] = 0dp[1] = 1
  4. 循环计算:从 2 到 n,依次计算 dp[i]
using System;class Program
{// 动态规划计算斐波那契数列的第n项static long Fibonacci(int n){if (n <= 1)return n;long[] dp = new long[n + 1];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; i++){dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}static void Main(){int n = 10; // 计算斐波那契数列的第10项long result = Fibonacci(n);Console.WriteLine($"Fibonacci of {n} is {result}");}
}

动态规划是一种非常强大的方法,可以显著提高算法的效率,特别是在解决具有重复子问题和最优子结构的问题时。

http://www.ritt.cn/news/1276.html

相关文章:

  • 平面设计主要学什么软件seo研究中心怎么了
  • 无代码做网站广州seo推广营销
  • 合肥做网站公司哪家好快速收录网
  • 网站的产品图片怎样做清晰合肥网站seo推广
  • wordpress模板开发教程seo软文代写
  • wordpress phpcms比较兰州模板网站seo价格
  • 网站顶端图片素材windows优化大师是自带的吗
  • 婚礼网站怎么做百度人工客服
  • 顺义网站建设百度热议
  • 网页微信二维码登录怎么实现seo可以提升企业网站的
  • 公司网站建设服务如何推广网上国网
  • 做棋牌网站建设多少钱最近的重大新闻
  • wordpress 解析漏洞seo如何优化图片
  • 你有网站 我做房东 只收佣金的网如何制作自己的网址
  • 吉林企业做网站关键词快速排名seo怎么优化
  • 建设企业网站前市场分析汕头seo外包公司
  • 网站空间香港主机十大品牌营销策划公司
  • 中恒建设职业技术培训学校网站广告推广平台网站
  • 外贸日文网站神起网络游戏推广平台
  • 个人可以做宣传片视频网站百度的推广广告
  • 网站开发语言有什么bt磁力搜索神器
  • 网站开发软件开发流程t和p在一起怎么做网站
  • 西安哪家公司制作响应式网站建设企业营销培训课程
  • 免费的网站开发软件百度百度一下一下
  • 网站建设 风险说明重庆seo公司
  • 国外网站做营销网络广告设计
  • 胶州胶东网站建设电商平台怎么注册
  • 1800做网站因为专业梅花seo 快速排名软件
  • 清湖网站建设企业管理培训
  • 学生作业 制作一个网站重庆seo公司排名