{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 선형 자료 구조"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 빗물 트래핑"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://leetcode.com/problems/trapping-rain-water/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "높이를 입력받아 비 온 후 얼마나 많은 물이 쌓일 수 있는지 계산하라\n",
    "\n",
    "입력:\n",
    "\n",
    "[0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]\n",
    "\n",
    "출력:\n",
    "6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trap(height):\n",
    "    if len(height) < 1:\n",
    "        return 0\n",
    "\n",
    "    water = 0\n",
    "    left = 0\n",
    "    right = len(height) - 1\n",
    "    top = height.index(max(height))\n",
    "    \n",
    "    left_max = height[left]\n",
    "    right_max = height[right]\n",
    "    \n",
    "    while left < right:\n",
    "        left_max = max(height[left], left_max)\n",
    "        right_max = max(height[right], right_max)\n",
    "             \n",
    "        if left < top:\n",
    "            water += left_max - height[left]\n",
    "            left += 1\n",
    "            \n",
    "        if right > top:\n",
    "            water += right_max - height[right]\n",
    "            right -= 1\n",
    "        \n",
    "    return water"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trap(height)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\tAccepted\t48 ms\t14.7 MB\tpython3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 풀이 1. 투 포인트\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trap(height):\n",
    "    if len(height) < 1:\n",
    "        return 0\n",
    "\n",
    "    water = 0\n",
    "    left = 0\n",
    "    right = len(height) - 1\n",
    "    \n",
    "    left_max = height[left]\n",
    "    right_max = height[right]\n",
    "    \n",
    "    while left < right:\n",
    "        left_max = max(height[left], left_max)\n",
    "        right_max = max(height[right], right_max)\n",
    "        \n",
    "        if left_max <= right_max:\n",
    "            water += left_max - height[left]\n",
    "            left += 1\n",
    "        else:\n",
    "            water += right_max - height[right]\n",
    "            right -= 1\n",
    "        \n",
    "    return water"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\tAccepted\t52 ms\t14.8 MB\tpython3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 풀이 2. 스택 쌓기"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trap(height):\n",
    "    stack = []\n",
    "    volume = 0\n",
    "    \n",
    "    for i in range(len(height)):\n",
    "        while stack and height[i] > height[stack[-1]]:\n",
    "            top = stack.pop()\n",
    "            \n",
    "            if not len(stack):\n",
    "                break\n",
    "            \n",
    "            distance = i - stack[-1] - 1\n",
    "            waters = min(height[i], height[stack[-1]]) - height[top]\n",
    "            \n",
    "            volume += distance * waters\n",
    "        \n",
    "        stack.append(i)\n",
    "        \n",
    "    return volume"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trap(height)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\tAccepted\t56 ms\t14.8 MB\tpython3"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}