1. 程式人生 > 其它 >一道演算法面試題

一道演算法面試題

  朋友去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 }; } } }