Created
April 1, 2026 22:35
-
-
Save syawin/8d408a169f0fbf04efccd46112dd37e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Valid Palindrome\n", | |
| "\n", | |
| "> Given a string s, return true if it is a palindrome, otherwise return false.\n", | |
| ">\n", | |
| "> A palindrome is a string that reads the same forward and backward. It is also case-insensitive and ignores all non-alphanumeric characters.\n", | |
| ">\n", | |
| "> Note: Alphanumeric characters consist of letters (A-Z, a-z) and numbers (0-9).\n", | |
| "\n", | |
| "## Examples\n", | |
| "\n", | |
| "### Example 1\n", | |
| "\n", | |
| "Input: `s = \"Was it a car or a cat I saw?\"`\n", | |
| "\n", | |
| "Output: `true`\n", | |
| "Explanation: After considering only alphanumerical characters we have \"wasitacaroracatisaw\", which is a palindrome.\n", | |
| "\n", | |
| "### Example 2\n", | |
| "\n", | |
| "Input: `s = \"tab a cat\"`\n", | |
| "\n", | |
| "Output: `false`\n", | |
| "Explanation: \"tabacat\" is not a palindrome.\n", | |
| "\n", | |
| "## Constraints:\n", | |
| "\n", | |
| "- 1 <= s.length <= 1000\n", | |
| "- s is made up of only printable ASCII characters." | |
| ], | |
| "id": "c481d24b58218a07" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 1 - 2 Pointers\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| " _We can reduce to $O(1)$ space by not creating a new string and just using parameter (i.e. skip if not\n", | |
| " `isLetterOrDigit()`._\n", | |
| "\n", | |
| "_Where $n$ is the number of `char`s in `s`._" | |
| ], | |
| "id": "19da626e0761338b" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun isPalindrome(s: String): Boolean {\n", | |
| " val palindrome = s.replace(Regex(\"[^a-zA-Z0-9]\"), \"\").lowercase()\n", | |
| " var l = 0\n", | |
| " var r = palindrome.lastIndex\n", | |
| " while (l < r) {\n", | |
| " if (palindrome[l]!=palindrome[r]) return false\n", | |
| " l++\n", | |
| " r--\n", | |
| " }\n", | |
| " return true\n", | |
| "}" | |
| ], | |
| "id": "9107dab1371b5c45", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Two Integer Sum 2\n", | |
| "\n", | |
| "> Given an array of integers numbers that is sorted in non-decreasing order.\n", | |
| ">\n", | |
| "> Return the indices (1-indexed) of two numbers, [index1, index2], such that they add up to a given target number target and index1 < index2. Note that index1 and index2 cannot be equal, therefore you may not use the same element twice.\n", | |
| ">\n", | |
| "> There will always be exactly one valid solution.\n", | |
| ">\n", | |
| "> Your solution must use $O(1)$ additional space.\n", | |
| "\n", | |
| "## Constraints\n", | |
| "\n", | |
| "- `2 <= numbers.length <= 1000`\n", | |
| "- `1000 <= numbers [1] <= 1000`\n", | |
| "- `1000 <= target <= 1000`" | |
| ], | |
| "id": "8d07504c22f5137b" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 1 - Nested Loops/Brute Force\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n^2)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(1)$\n", | |
| "\n", | |
| "_Where $n$ is the size of `nums`._" | |
| ], | |
| "id": "7dd3571b7c294a4e" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_5_jupyter", | |
| "Line_6_jupyter", | |
| "Line_4_jupyter", | |
| "Line_7_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun twoSum(numbers: IntArray, target: Int): IntArray {\n", | |
| " for (i in 0 until numbers.lastIndex) {\n", | |
| " for (j in i + 1 until numbers.size) {\n", | |
| " if (numbers[i] + numbers[j] == target) return intArrayOf(i + 1, j + 1)\n", | |
| " }\n", | |
| " }\n", | |
| " return intArrayOf(0, 0)\n", | |
| "}\n", | |
| "\n", | |
| "val nums = intArrayOf(1, 2, 3, 4)\n", | |
| "twoSum(nums, 3).joinToString(\",\", \"[\", \"]\")" | |
| ], | |
| "id": "147d26e995a76cd5", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 2 - 2 Pointers\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(1)$\n", | |
| "\n", | |
| "_Where $n$ is the size of nums._" | |
| ], | |
| "id": "1c16519edf06aac9" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_8_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun twoSum(numbers: IntArray, target: Int): IntArray {\n", | |
| " var l = 0\n", | |
| " var r = numbers.lastIndex\n", | |
| " while (l < r) {\n", | |
| " if (numbers[l] + numbers[r] == target) break\n", | |
| " else if (numbers[l] + numbers[r] < target) l++\n", | |
| " else if (numbers[l] + numbers[r] > target) r--\n", | |
| " }\n", | |
| " return intArrayOf(l+1, r+1)\n", | |
| "}\n", | |
| "\n", | |
| "val nums = intArrayOf(1, 2, 3, 4)\n", | |
| "twoSum(nums, 3).joinToString(\",\", \"[\", \"]\")" | |
| ], | |
| "id": "693ff6575763c8ba", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# 3 Sum\n", | |
| "\n", | |
| "<!-- threesome lol ;p -->\n", | |
| "\n", | |
| "> Given an integer array `nums` return all the triplets, `[nums[i], nums[j], nums[k]]` where `nums[i] + nums[j] +\n", | |
| "> nums[k] == 0`\n", | |
| "\n", | |
| "## Solution 1 — Brute Force — Triple-nested loops\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n^3)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(n^3)$\n", | |
| "\n", | |
| "_Where $n$ is the number of elements._" | |
| ], | |
| "id": "37c909c03107958e" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_13_jupyter", | |
| "Line_10_jupyter", | |
| "Line_11_jupyter", | |
| "Line_9_jupyter", | |
| "Line_14_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun threeSum(nums: IntArray): List<List<Int>> {\n", | |
| " val result = MutableList(0) { listOf<Int>() }\n", | |
| " val sort = nums.sorted()\n", | |
| " for (i in 0..sort.lastIndex - 1) {\n", | |
| " for (j in i + 1 until sort.lastIndex) {\n", | |
| " for (k in j + 1..sort.lastIndex) {\n", | |
| " if (sort[i] + sort[j] + sort[k] == 0) {\n", | |
| " result.add(listOf(sort[i], sort[j], sort[k]))\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " return result.distinct()\n", | |
| "}\n", | |
| "\n", | |
| "val nums1 = intArrayOf(-1, 0, 1, 2, -1, -4)\n", | |
| "println(threeSum(nums1).joinToString(\",\"))\n", | |
| "\n", | |
| "val out1 = listOf(listOf(-1, -1, 2), listOf(-1, 0, 1))\n", | |
| "\n", | |
| "val nums2 = intArrayOf(0, 1, 1)\n", | |
| "val out2 = emptyList<List<Int>>()\n", | |
| "\n", | |
| "val nums3 = intArrayOf(0, 0, 0)\n", | |
| "val out3 = listOf(listOf(0, 0, 0))" | |
| ], | |
| "id": "d29c676cc7c0e441", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 2 - Two Pointers\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n^2)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| " - $O(1)$ or $O(n)$ extra space depending on the sorting algorithm.\n", | |
| " - $O(m)$ space for the output list.\n", | |
| "\n", | |
| "_Where $n$ is the number of elements in `nums` and $m$ is the number of triplets._" | |
| ], | |
| "id": "ef4829869770e139" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_13_jupyter", | |
| "Line_20_jupyter", | |
| "Line_21_jupyter", | |
| "Line_5_jupyter", | |
| "Line_11_jupyter", | |
| "Line_4_jupyter", | |
| "Line_9_jupyter", | |
| "Line_12_jupyter", | |
| "Line_18_jupyter", | |
| "Line_17_jupyter", | |
| "Line_10_jupyter", | |
| "Line_16_jupyter", | |
| "Line_8_jupyter", | |
| "Line_19_jupyter", | |
| "Line_15_jupyter", | |
| "Line_6_jupyter", | |
| "Line_14_jupyter", | |
| "Line_23_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun threeSum(nums: IntArray): List<List<Int>> {\n", | |
| " val result = mutableListOf<List<Int>>()\n", | |
| " nums.sort()\n", | |
| " for (i in 0 until nums.lastIndex) {\n", | |
| " if (i > 0 && nums[i] == nums[i - 1]) continue\n", | |
| " val complement = 0 - nums[i]\n", | |
| " var l = i + 1\n", | |
| " var r = nums.lastIndex\n", | |
| " while (l < r) {\n", | |
| " if (l > (i + 1) && nums[l] == nums[l - 1]) l++\n", | |
| " else if (r < nums.lastIndex && nums[r] == nums[r + 1]) r--\n", | |
| " else if (nums[l] + nums[r] == complement) {\n", | |
| " result.add(listOf(nums[i], nums[l], nums[r]))\n", | |
| " l++\n", | |
| " } else if (nums[l] + nums[r] < complement) l++\n", | |
| " else if (nums[l] + nums[r] > complement) r--\n", | |
| " }\n", | |
| " }\n", | |
| " return result\n", | |
| "}\n", | |
| "\n", | |
| "val nums1 = intArrayOf(-1, 0, 1, 2, -1, -4)\n", | |
| "println(threeSum(nums1).joinToString(\",\"))\n", | |
| "\n", | |
| "val nums3 = intArrayOf(0, 0, 0, 0)\n", | |
| "println(threeSum(nums3).joinToString(\",\"))" | |
| ], | |
| "id": "28b63439f615edf8", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### Hint\n", | |
| "\n", | |
| "> Think about what changes you'd need so that:\n", | |
| ">\n", | |
| "> 1. You find **all** triplets for a given `i`, not just the first one.\n", | |
| "> 2. You skip duplicate values of `sort[i]`, `sort[l]`, and `sort[r]`." | |
| ], | |
| "id": "b3326f565fa485fc" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### Solution from Neetcode.io\n", | |
| "\n", | |
| "_This seems cleaner to me. Little confused on the `a` val. I think the `break` check acts as a way to short-circuit\n", | |
| "because when `a > 0`, due to the sorted property, we know `nums[l]` & `nums[r]` will also be positive and because we\n", | |
| "are trying to sum to 0, it is no longer possible to reach it if we are dealing only with positive values._" | |
| ], | |
| "id": "8135b464c316db2c" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun threeSum(nums: IntArray): List<List<Int>> {\n", | |
| " val res = mutableListOf<List<Int>>()\n", | |
| " nums.sort()\n", | |
| "\n", | |
| " for (i in nums.indices) {\n", | |
| " val a = nums[i]\n", | |
| " if (a > 0) break\n", | |
| " if (i > 0 && a == nums[i - 1]) continue\n", | |
| "\n", | |
| " var l = i + 1\n", | |
| " var r = nums.size - 1\n", | |
| " while (l < r) {\n", | |
| " val threeSum = a + nums[l] + nums[r]\n", | |
| " when {\n", | |
| " threeSum > 0 -> r--\n", | |
| " threeSum < 0 -> l++\n", | |
| " else -> {\n", | |
| " res.add(listOf(a, nums[l], nums[r]))\n", | |
| " l++\n", | |
| " r--\n", | |
| " while (l < r && nums[l] == nums[l - 1]) {\n", | |
| " l++\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| "\n", | |
| " return res\n", | |
| "}" | |
| ], | |
| "id": "eb9f4210e56c779e", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Container with Most Water\n", | |
| "\n", | |
| "> You are given an integer array `heights` where `heights[i]` represents the height of the $i^{th}$ bar.\n", | |
| ">\n", | |
| "> You may choose any two bars to form a container. Return the _maximum_ amount of water a container can store.\n", | |
| "\n", | |
| "## Examples\n", | |
| "\n", | |
| "### Example 1\n", | |
| "\n", | |
| "```kotlin\n", | |
| "val heights = [1,7,2,5,4,7,3,6]\n", | |
| "val result = 36\n", | |
| "```" | |
| ], | |
| "id": "6a3b71922328618b" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_14_jupyter" | |
| ] | |
| }, | |
| "tags": [ | |
| "data vis" | |
| ] | |
| }, | |
| "cell_type": "code", | |
| "source": "%use lets-plot\nimport org.jetbrains.letsPlot.*\nimport org.jetbrains.letsPlot.geom.*\nimport org.jetbrains.letsPlot.scale.*\nimport org.jetbrains.letsPlot.themes.*\nimport kotlin.math.min\n\n// Heights matching the screenshot\nval heights = listOf(1, 7, 2, 5, 4, 7, 3, 6)\n\n// Two green \"container edge\" bars (same positions as the screenshot)\nval left = 1\nval right = 7\nval waterH = min(heights[left], heights[right])\n\nval df = mapOf(\n \"x\" to heights.indices.toList(),\n \"h\" to heights,\n \"kind\" to heights.indices.map { if (it == left || it == right) \"edge\" else \"bar\" },\n)\n\nval waterDf = mapOf(\n \"xmin\" to listOf(left + 0.5),\n \"xmax\" to listOf(right - 0.5),\n \"ymin\" to listOf(0),\n \"ymax\" to listOf(waterH),\n)\n\nletsPlot(df) + geomRect(\n data = waterDf,\n fill = \"#8ecbff\",\n alpha = 0.55,\n) {\n xmin = \"xmin\"; xmax = \"xmax\"\n ymin = \"ymin\"; ymax = \"ymax\"\n} + geomBar(\n stat = Stat.identity,\n width = 0.35,\n color = \"black\",\n) {\n x = \"x\"\n y = \"h\"\n fill = \"kind\"\n} + scaleFillManual(\n values = listOf(\"#000000\", \"#7fbf56\"),\n limits = listOf(\"bar\", \"edge\"),\n guide = \"none\",\n) + scaleYContinuous(\n breaks = listOf(0, 2, 4, 6, 8),\n limits = Pair(0, 8),\n) + scaleXContinuous(breaks = emptyList<Int>()) + themeClassic() + theme(\n axisTitleX = elementBlank(),\n axisTitleY = elementBlank(),\n axisTicksX = elementBlank(),\n axisTextX = elementBlank(),\n panelGrid = elementBlank(),\n axisLine = elementLine(size = 1.2),\n)", | |
| "id": "6fe0349d38a8c8a2", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 1 - Brute Force - Nested Loops\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n^2)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(1)$\n", | |
| "\n", | |
| "_Where $n$ is the size of the array._" | |
| ], | |
| "id": "6b2e5ee6fe5bc0b6" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_17_jupyter", | |
| "Line_19_jupyter", | |
| "Line_15_jupyter", | |
| "Line_20_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun maxArea(heights: IntArray): Int {\n", | |
| " var maxArea = 0\n", | |
| " for (i in 0 until heights.lastIndex) {\n", | |
| " for (j in i + 1 until heights.size) {\n", | |
| " val area = (j - i) * minOf(heights[i], heights[j])\n", | |
| " maxArea = maxOf(area, maxArea)\n", | |
| " }\n", | |
| " }\n", | |
| " return maxArea\n", | |
| "}\n", | |
| "\n", | |
| "var heights = intArrayOf(1, 7, 2, 5, 4, 7, 3, 6)\n", | |
| "maxArea(heights)" | |
| ], | |
| "id": "bd77461ded67b9c", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 2 -\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(1)$\n", | |
| "\n", | |
| "_Where $n$ is the size of the array._" | |
| ], | |
| "id": "4fba26f05867ab12" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_25_jupyter", | |
| "Line_31_jupyter", | |
| "Line_28_jupyter", | |
| "Line_30_jupyter", | |
| "Line_27_jupyter", | |
| "Line_22_jupyter", | |
| "Line_23_jupyter", | |
| "Line_26_jupyter", | |
| "Line_29_jupyter", | |
| "Line_32_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun maxArea(heights: IntArray): Int {\n", | |
| " var maxArea = 0\n", | |
| " var l = 0;\n", | |
| " var r = heights.lastIndex;\n", | |
| " while (l < r) {\n", | |
| " val area = (r - l) * minOf(heights[l], heights[r])\n", | |
| " maxArea = maxOf(area, maxArea)\n", | |
| " if (heights[l] > heights[r]) r--\n", | |
| " else l++\n", | |
| " }\n", | |
| " return maxArea\n", | |
| "}\n", | |
| "\n", | |
| "var heights = intArrayOf(1, 7, 2, 5, 4, 7, 3, 6)\n", | |
| "maxArea(heights)\n", | |
| "\n", | |
| "heights = intArrayOf(\n", | |
| " 1,\n", | |
| " 7,\n", | |
| " 2,\n", | |
| " 5,\n", | |
| " 12,\n", | |
| " 3,\n", | |
| " 500,\n", | |
| " 500,\n", | |
| " 7,\n", | |
| " 8,\n", | |
| " 4,\n", | |
| " 7,\n", | |
| " 3,\n", | |
| " 6,\n", | |
| ")\n", | |
| "maxArea(heights)" | |
| ], | |
| "id": "87d26992a3a138b8", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# Trapping Rainwater\n", | |
| "\n", | |
| "> You are given an array of non-negative integers height which represent an elevation map. Each value `height[i]` represents the height of a bar, which has a width of 1.\n", | |
| ">\n", | |
| "> Return the maximum area of water that can be trapped between the bars.\n", | |
| "\n", | |
| "## Examples\n", | |
| "\n", | |
| "```\n", | |
| "Input: height = [0,2,0,3,1,0,1,3,2,1]\n", | |
| "Output: 9\n", | |
| "```\n", | |
| "\n", | |
| "## Solution 1 - Brute Force\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n^2)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "_Where $n$ is the size of the array._" | |
| ], | |
| "id": "bfbee9c384ad35" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_20_jupyter", | |
| "Line_18_jupyter", | |
| "Line_17_jupyter", | |
| "Line_21_jupyter", | |
| "Line_16_jupyter", | |
| "Line_19_jupyter", | |
| "Line_22_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun trap(height: IntArray): Int {\n", | |
| " if (height.size <= 2) return 0\n", | |
| " val volumes = IntArray(height.size)\n", | |
| " for (i in 1 until height.lastIndex) {\n", | |
| " val l = height.slice(0 until i).max()\n", | |
| " val r = height.slice(i until height.size).max()\n", | |
| " volumes[i] = minOf(l,r) - height[i]\n", | |
| " print(\"|$i: $l,$r|\\t\")\n", | |
| " }\n", | |
| " println()\n", | |
| " println(volumes.joinToString(\",\"))\n", | |
| " return volumes.sum()\n", | |
| "}\n", | |
| "\n", | |
| "val input = intArrayOf(0, 2, 0, 3, 1, 0, 1, 3, 2, 1)\n", | |
| "trap(input)" | |
| ], | |
| "id": "9069ca5f4a032073", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 2 - Prefix & Suffix Array\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "_Where $n$ is the size of `heights` array._" | |
| ], | |
| "id": "15a0bdf49c643838" | |
| }, | |
| { | |
| "metadata": { | |
| "executionRelatedData": { | |
| "compiledClasses": [ | |
| "Line_13_jupyter", | |
| "Line_5_jupyter", | |
| "Line_11_jupyter", | |
| "Line_4_jupyter", | |
| "Line_9_jupyter", | |
| "Line_12_jupyter", | |
| "Line_25_jupyter", | |
| "Line_24_jupyter", | |
| "Line_10_jupyter", | |
| "Line_8_jupyter", | |
| "Line_15_jupyter", | |
| "Line_6_jupyter", | |
| "Line_14_jupyter", | |
| "Line_23_jupyter", | |
| "Line_26_jupyter" | |
| ] | |
| } | |
| }, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun trap(height: IntArray): Int {\n", | |
| " if (height.size <= 2) return 0\n", | |
| " val maxima = IntArray(height.size) { 0 }\n", | |
| " var currMax = height[0]\n", | |
| " maxima[0] = height[0]\n", | |
| " for (i in 1 until height.lastIndex) { // forward pass\n", | |
| " currMax = maxOf(currMax, height[i])\n", | |
| " maxima[i] = currMax\n", | |
| " }\n", | |
| " currMax = height.last()\n", | |
| " maxima[maxima.lastIndex] = height.last()\n", | |
| " for (i in height.lastIndex - 1 downTo 1) {\n", | |
| " currMax = maxOf(currMax, height[i])\n", | |
| " maxima[i] = minOf(maxima[i], currMax)\n", | |
| " }\n", | |
| " for(i in maxima.indices) {\n", | |
| " maxima[i] -= height[i]\n", | |
| " }\n", | |
| " return maxima.sum()\n", | |
| "}\n", | |
| "\n", | |
| "val input = intArrayOf(0, 2, 0, 3, 1, 0, 1, 3, 2, 1)\n", | |
| "trap(input)" | |
| ], | |
| "id": "137a995a0d97efac", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 3 - Stack\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "_Where $n$ is the size of `heights` array._" | |
| ], | |
| "id": "8ff5e06e71f106f" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun trap(height: IntArray): Int {\n", | |
| " if (height.size <= 2) return 0\n", | |
| " var res = 0\n", | |
| " val stack = ArrayDeque<Int>()\n", | |
| "\n", | |
| " for (i in height.indices) {\n", | |
| " while (stack.isNotEmpty() && height[i] > height[stack.first()]) {\n", | |
| " val top = stack.removeFirst()\n", | |
| " if (stack.isNotEmpty()) {\n", | |
| " val left = stack.first()\n", | |
| " val right = height[i]\n", | |
| " val h = minOf(right, height[left]) - height[top]\n", | |
| " val w = i - left - 1\n", | |
| " res += h * w\n", | |
| " }\n", | |
| " }\n", | |
| " stack.addFirst(i)\n", | |
| " }\n", | |
| " return res\n", | |
| "}" | |
| ], | |
| "id": "9969280d674f9b8c", | |
| "outputs": [], | |
| "execution_count": null | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## Solution 4 - 2 Pointers\n", | |
| "\n", | |
| "- Time complexity:\n", | |
| "$O(n)$\n", | |
| "\n", | |
| "- Space complexity:\n", | |
| "$O(1)$\n", | |
| "\n", | |
| "_Where $n$ is the size of `heights` array._" | |
| ], | |
| "id": "ca64aba18fadc653" | |
| }, | |
| { | |
| "metadata": {}, | |
| "cell_type": "code", | |
| "source": [ | |
| "fun trap(height: IntArray): Int {\n", | |
| " if (height.size <= 2) return 0\n", | |
| " var res = 0\n", | |
| " var l = 0\n", | |
| " var r = height.lastIndex\n", | |
| " var leftMax = height[l]\n", | |
| " var rightMax = height[r]\n", | |
| " while (l < r) {\n", | |
| " if (leftMax < rightMax) {\n", | |
| " l++\n", | |
| " leftMax = maxOf(leftMax, height[l])\n", | |
| " res += leftMax - height[l]\n", | |
| " } else {\n", | |
| " r--\n", | |
| " rightMax = maxOf(rightMax, height[r])\n", | |
| " res += rightMax - height[r]\n", | |
| " }\n", | |
| " }\n", | |
| " return res\n", | |
| "}" | |
| ], | |
| "id": "1379f8740c5382c1", | |
| "outputs": [], | |
| "execution_count": null | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Kotlin", | |
| "language": "kotlin", | |
| "name": "kotlin" | |
| }, | |
| "language_info": { | |
| "name": "kotlin", | |
| "version": "2.2.20", | |
| "mimetype": "text/x-kotlin", | |
| "file_extension": ".kt", | |
| "pygments_lexer": "kotlin", | |
| "codemirror_mode": "text/x-kotlin", | |
| "nbconvert_exporter": "" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment