一道算法面试题-接雨水

  朋友去XX书面试IOS开发,面试有一道算法题做不出来,事后发给我看了一下,然而,我不会OC,就用C#写了一下,题目如下:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
 
示例 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 个单位的雨水(蓝色部分表示雨水)。 示例 2:
输入:height = [4,2,0,3,2,5]输出:9

 

  解题思路:途中蓝色部分是储水位置,特点:蓝色区块左右两侧必须都有比自己高的柱子,也就是[1,0,1]、[3、0、0、2]这种结构。

  比较简单的算法是:

  1.我们可以从最下面一行逐行进行计算,当数值为0,且两边能找到为0节点的时候,存在储水空间
  2.每一行计算完成之后,把集合的数值全部-1,再次重复第一步

  3.重复上面两步,总共要计算集合中最大值的行数。

具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        private static List<int> NumList { get; set; }
        static void Main(string[] args)
        {
            InitNumList();//初始化集合
            var total = 0;//总共储水量
            var max = NumList.Max();//最高柱子
            var iCount = NumList.Count;//集合数量
            for (int l = 0; l < max; l++)//进行分行计算
            {
                var line = 0;//每一行的储水量
                var start = -1;//定义每一个储水空间的起始节点
                for (int i = 0; i < iCount; i++)//循环当前行
                {
                    var num = NumList[i];
                    if (num > 0 && start == -1)//取开始节点
                    {
                        start = i;
                    }
                    else if (num > 0 && start > -1)//取结束节点
                    {
                        var water = i - start - 1;//两节点间的储水量
                        if (water > 0)//当water=0的时候,开始节点和结束节点刚好相同,这时候没办法储水
                        {
                            total += i - start - 1;//累加总储水量
                            line += i - start - 1;//累加当前行储水量
                        }
                        start = i;//重置开始节点
                    }
                }
                Console.WriteLine($"line:{line}");
                for (int i = 0; i < iCount; i++)//循环将集合里的非0数字全部-1
                {
                    if (NumList[i] > 0)
                    {
                        NumList[i]--;
                    }
                }
            }
            Console.WriteLine($"total:{total}");
        }

        /// <summary>
        /// 初始化集合
        /// </summary>
        private static void InitNumList()
        {
            //NumList = new List<int>() { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
            NumList = new List<int>() { 4, 2, 0, 3, 2, 5 };
        }
    }
}

 

posted on 2022-03-07 14:15  懒蛋君  阅读(87)  评论(0编辑  收藏  举报

导航