├── add-two-numbers.js ├── container-with-most-water.js ├── integer-to-roman.js ├── longest-common-prefix.js ├── longest-palindrome-substring.js ├── longest-substring-without-repeating-characters.js ├── median-of-two-sorted-arrays.js ├── palindrome-number.js ├── regular-expression-matching.js ├── reverse-integer.js ├── roman-to-integer.js ├── shift-2d-grid.js ├── string-to-integer-atoi.js ├── teemo-attacking.js └── zigzag-conversion.js /add-two-numbers.js: -------------------------------------------------------------------------------- 1 | class ListNode { 2 | constructor(val, next) { 3 | this.val = val === undefined ? 0 : val; 4 | this.next = next === undefined ? null : next; 5 | } 6 | } 7 | 8 | /** 9 | * @param {ListNode} l1 10 | * @param {ListNode} l2 11 | * @return {ListNode} 12 | */ 13 | 14 | // Runtime: 209 ms, faster than 14.10% of JavaScript online submissions for Add Two Numbers. 15 | // Memory Usage: 47.3 MB, less than 69.79% of JavaScript online submissions for Add Two Numbers. 16 | const addTwoNumbers = (l1, l2) => { 17 | const calc = (l1, l2, sumNode, carry) => { 18 | const val1 = l1 ? l1.val : 0; 19 | const val2 = l2 ? l2.val : 0; 20 | const subSum = val1 + val2 + (carry ? 1 : 0); 21 | const shouldCarry = subSum > 9; 22 | sumNode.val = Math.round((subSum / 10 - Math.floor(subSum / 10)) * 10); 23 | if ((l1 && l1.next) || (l2 && l2.next)) { 24 | sumNode.next = new ListNode(); 25 | calc( 26 | l1 ? l1.next : undefined, 27 | l2 ? l2.next : undefined, 28 | sumNode.next, 29 | shouldCarry 30 | ); 31 | } else if (shouldCarry) { 32 | sumNode.next = new ListNode(1); 33 | } 34 | }; 35 | const head = new ListNode(); 36 | calc(l1, l2, head, false); 37 | return head; 38 | }; 39 | -------------------------------------------------------------------------------- /container-with-most-water.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} height 3 | * @return {number} 4 | */ 5 | 6 | // Runtime: 89 ms, faster than 71.23% of JavaScript online submissions for Container With Most Water. 7 | // Memory Usage: 49.2 MB, less than 96.56% of JavaScript online submissions for Container With Most Water. 8 | const maxArea = (height) => { 9 | let largest = -1; 10 | let left = 0; 11 | let right = height.length - 1; 12 | while (left < right) { 13 | let area = Math.min(height[left], height[right]) * (right - left); 14 | if (largest < area) { 15 | largest = area; 16 | } 17 | if (height[left] < height[right]) { 18 | left++; 19 | } else { 20 | right--; 21 | } 22 | } 23 | return largest; 24 | }; 25 | -------------------------------------------------------------------------------- /integer-to-roman.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {string} 4 | */ 5 | 6 | // Runtime: 136 ms, faster than 79.26% of JavaScript online submissions for Integer to Roman. 7 | // Memory Usage: 46.3 MB, less than 98.72% of JavaScript online submissions for Integer to Roman. 8 | const values = [ 9 | { value: 1000, symbol: 'M' }, 10 | { value: 900, symbol: 'CM' }, 11 | { value: 500, symbol: 'D' }, 12 | { value: 400, symbol: 'CD' }, 13 | { value: 100, symbol: 'C' }, 14 | { value: 90, symbol: 'XC' }, 15 | { value: 50, symbol: 'L' }, 16 | { value: 40, symbol: 'XL' }, 17 | { value: 10, symbol: 'X' }, 18 | { value: 9, symbol: 'IX' }, 19 | { value: 5, symbol: 'V' }, 20 | { value: 4, symbol: 'IV' }, 21 | { value: 1, symbol: 'I' } 22 | ]; 23 | 24 | const intToRoman = (num) => { 25 | let result = ''; 26 | for (let i = 0; i < values.length; i++) { 27 | if (values[i].value > num) { 28 | continue; 29 | } 30 | result += values[i].symbol.repeat(num / values[i].value); 31 | num -= ((num / values[i].value) | 0) * values[i].value; 32 | } 33 | return result; 34 | }; 35 | -------------------------------------------------------------------------------- /longest-common-prefix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} strs 3 | * @return {string} 4 | */ 5 | 6 | // Runtime: 73 ms, faster than 71.86% of JavaScript online submissions for Longest Common Prefix. 7 | // Memory Usage: 42.3 MB, less than 83.82% of JavaScript online submissions for Longest Common Prefix. 8 | const longestCommonPrefix = (strs) => { 9 | if (strs.length === 1) { 10 | return strs[0]; 11 | } 12 | let longestPrefix = ''; 13 | while (strs.every((str) => !!str && str.startsWith(longestPrefix))) { 14 | let newPrefix = strs[0].substring(0, longestPrefix.length + 1); 15 | if (longestPrefix.length === strs[0].length) { 16 | return longestPrefix; 17 | } 18 | if (newPrefix.length > longestPrefix.length) { 19 | longestPrefix = newPrefix; 20 | } 21 | } 22 | return longestPrefix.slice(0, -1); 23 | }; 24 | -------------------------------------------------------------------------------- /longest-palindrome-substring.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string} 4 | */ 5 | 6 | // Runtime: 174 ms, faster than 58.53% of JavaScript online submissions for Longest Palindromic Substring. 7 | // Memory Usage: 44.9 MB, less than 75.83% of JavaScript online submissions for Longest Palindromic Substring. 8 | const longestPalindrome = (s) => { 9 | if (s.length === 1) { 10 | return s; 11 | } 12 | 13 | const getPalindrome = (s, left, right) => { 14 | while (left >= 0 && right < s.length && s[left] === s[right]) { 15 | left--; 16 | right++; 17 | } 18 | return s.substring(left + 1, right); 19 | }; 20 | 21 | let longest = ""; 22 | 23 | for (let i = 0; i < s.length; i++) { 24 | const oddPal = getPalindrome(s, i, i); 25 | const evenPal = getPalindrome(s, i, i + 1); 26 | 27 | longest = 28 | oddPal.length > evenPal.length 29 | ? oddPal.length > longest.length 30 | ? oddPal 31 | : longest 32 | : evenPal.length > longest.length 33 | ? evenPal 34 | : longest; 35 | } 36 | return longest; 37 | }; 38 | -------------------------------------------------------------------------------- /longest-substring-without-repeating-characters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | 6 | // Runtime: 97 ms, faster than 85.41% of JavaScript online submissions for Longest Substring Without Repeating Characters. 7 | // Memory Usage: 47.1 MB, less than 73.13% of JavaScript online submissions for Longest Substring Without Repeating Characters. 8 | const lengthOfLongestSubstring = (s) => { 9 | let longestSubstring = 0; 10 | let seenChars = new Set(); 11 | let left = 0; 12 | 13 | for (let right = 0; right < s.length; right++) { 14 | while (seenChars.has(s[right])) { 15 | seenChars.delete(s[left]); 16 | left++; 17 | } 18 | seenChars.add(s[right]); 19 | longestSubstring = Math.max(seenChars.size, longestSubstring); 20 | } 21 | 22 | return longestSubstring; 23 | }; 24 | -------------------------------------------------------------------------------- /median-of-two-sorted-arrays.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number} 5 | */ 6 | 7 | // Runtime: 180 ms, faster than 33.30% of JavaScript online submissions for Median of Two Sorted Arrays. 8 | // Memory Usage: 48.1 MB, less than 44.68% of JavaScript online submissions for Median of Two Sorted Arrays. 9 | const findMedianSortedArrays = (nums1, nums2) => { 10 | const mergedList = [...nums1, ...nums2].sort((a, b) => a - b); 11 | if (mergedList.length % 2) { 12 | return mergedList[Math.floor(mergedList.length / 2)]; 13 | } 14 | return ( 15 | (mergedList[mergedList.length / 2] + 16 | mergedList[mergedList.length / 2 - 1]) / 17 | 2 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /palindrome-number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {boolean} 4 | */ 5 | 6 | // Runtime: 184 ms, faster than 82.64% of JavaScript online submissions for Palindrome Number. 7 | // Memory Usage: 50.6 MB, less than 84.85% of JavaScript online submissions for Palindrome Number. 8 | const isPalindrome = (x) => { 9 | let xString = String(x); 10 | for (let i = 0; i < xString.length / 2; i++) { 11 | let right = xString.length - i - 1; 12 | if (i !== right) { 13 | if (xString.charAt(i) !== xString.charAt(right)) { 14 | return false; 15 | } 16 | } 17 | } 18 | return true; 19 | }; 20 | 21 | // Runtime: 146 ms, faster than 96.28% of JavaScript online submissions for Palindrome Number. 22 | // Memory Usage: 50.8 MB, less than 71.90% of JavaScript online submissions for Palindrome Number. 23 | const isPalindromeWithBitwise = (x) => { 24 | if (x < 0) { 25 | return false; 26 | } 27 | 28 | let numbers = []; 29 | 30 | while (x > 0) { 31 | numbers.push(x % 10); 32 | x = (x / 10) | 0; 33 | } 34 | let end = numbers.length - 1; 35 | for (let i = 0; i < end / 2; i++) { 36 | if (numbers[i] !== numbers[end - i]) { 37 | return false; 38 | } 39 | } 40 | return true; 41 | }; 42 | -------------------------------------------------------------------------------- /regular-expression-matching.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {string} p 4 | * @return {boolean} 5 | */ 6 | 7 | // Runtime: 138 ms, faster than 58.86% of JavaScript online submissions for Regular Expression Matching. 8 | // Memory Usage: 42.3 MB, less than 96.27% of JavaScript online submissions for Regular Expression Matching. 9 | const isMatch = (string, regex) => { 10 | return !!string.match(`^${regex}$`); 11 | }; 12 | -------------------------------------------------------------------------------- /reverse-integer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {number} 4 | */ 5 | 6 | // Runtime: 91 ms, faster than 63.57% of JavaScript online submissions for Reverse Integer. 7 | // Memory Usage: 43.9 MB, less than 72.48% of JavaScript online submissions for Reverse Integer. 8 | const reverse = (x) => { 9 | let result = 0; 10 | if (x < 10 && x > -10) { 11 | return x; 12 | } 13 | const sign = x < 0 ? -1 : 1; 14 | input = Math.abs(x); 15 | while (input > 0) { 16 | const rightDigit = input % 10; 17 | result = result * 10 + rightDigit; 18 | input = (input / 10) | 0; 19 | } 20 | if (result > Math.pow(2, 31)) { 21 | return 0; 22 | } 23 | return result * sign; 24 | }; 25 | -------------------------------------------------------------------------------- /roman-to-integer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | 6 | // Runtime: 159 ms, faster than 69.20% of JavaScript online submissions for Roman to Integer. 7 | // Memory Usage: 47.4 MB, less than 52.67% of JavaScript online submissions for Roman to Integer. 8 | const symbols = { 9 | I: 1, 10 | V: 5, 11 | X: 10, 12 | L: 50, 13 | C: 100, 14 | D: 500, 15 | M: 1000 16 | }; 17 | 18 | const romanToInt = (s) => { 19 | let result = 0; 20 | for (let i = 0; i < s.length; i++) { 21 | if (s[i + 1] && symbols[s[i + 1]] > symbols[s[i]]) { 22 | result -= symbols[s[i]]; 23 | } else { 24 | result += symbols[s[i]]; 25 | } 26 | } 27 | return result; 28 | }; 29 | -------------------------------------------------------------------------------- /shift-2d-grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} grid 3 | * @param {number} k 4 | * @return {number[][]} 5 | */ 6 | 7 | // Runtime: 128 ms, faster than 50.65% of JavaScript online submissions for Shift 2D Grid. 8 | // Memory Usage: 47.3 MB, less than 77.92% of JavaScript online submissions for Shift 2D Grid. 9 | const shiftGrid = (grid, k) => { 10 | const columnLength = grid.length; 11 | 12 | const newGrid = []; 13 | for (let i = 0; i < columnLength; i++) { 14 | newGrid[i] = []; 15 | } 16 | 17 | for (let y = 0; y < columnLength; y++) { 18 | const rowLength = grid[y].length; 19 | for (let x = 0; x < rowLength; x++) { 20 | const newPos = y * rowLength + (x % rowLength) + k; 21 | newGrid[Math.floor(newPos / rowLength) % columnLength][ 22 | newPos % rowLength 23 | ] = grid[y][x]; 24 | } 25 | } 26 | 27 | return newGrid; 28 | }; 29 | 30 | /** 31 | * @param {number[][]} grid 32 | * @param {number} k 33 | * @return {number[][]} 34 | */ 35 | 36 | // Runtime: 88 ms, faster than 89.61% of JavaScript online submissions for Shift 2D Grid. 37 | // Memory Usage: 48.8 MB, less than 24.68% of JavaScript online submissions for Shift 2D Grid. 38 | const shiftGridFlatten = (grid, k) => { 39 | const flatGrid = grid.flat(); 40 | if (k % flatGrid.length === 0) { 41 | return grid; 42 | } 43 | const cutoff = flatGrid.length - (k % flatGrid.length); 44 | const shifted = [...flatGrid.slice(cutoff), ...flatGrid.slice(0, cutoff)]; 45 | 46 | const newGrid = []; 47 | for (let i = 0; i < grid.length; i++) { 48 | newGrid[i] = []; 49 | for (let j = 0; j < grid[i].length; j++) { 50 | newGrid[i][j] = shifted[i * grid[i].length + (j % grid[i].length)]; 51 | } 52 | } 53 | return newGrid; 54 | }; 55 | -------------------------------------------------------------------------------- /string-to-integer-atoi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | 6 | // Runtime: 70 ms, faster than 95.43% of JavaScript online submissions for String to Integer (atoi). 7 | // Memory Usage: 45 MB, less than 46.32% of JavaScript online submissions for String to Integer (atoi). 8 | var myAtoi = function (s) { 9 | const clamp = (num) => 10 | Math.min(Math.max(num, -Math.pow(2, 31)), Math.pow(2, 31) - 1); 11 | 12 | const finalResult = (result) => { 13 | return clamp(result ? result : 0); 14 | }; 15 | 16 | let startedParsing = false; 17 | 18 | let result = 0, 19 | sign; 20 | for (let i = 0; i < s.length; i++) { 21 | if (s[i] === " ") { 22 | if (startedParsing) { 23 | return finalResult(result * sign); 24 | } else if (sign) { 25 | return finalResult(result * sign); 26 | } 27 | continue; 28 | } 29 | if (s[i] === "-" || s[i] === "+") { 30 | if (startedParsing) { 31 | return finalResult(result * sign); 32 | } 33 | if (sign) { 34 | return 0; 35 | } 36 | sign = s[i] === "-" ? -1 : 1; 37 | continue; 38 | } 39 | sign = sign ? sign : 1; 40 | if (s[i] === "0" && !startedParsing) { 41 | startedParsing = true; 42 | continue; 43 | } 44 | if (!["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(s[i])) { 45 | return finalResult(result * sign); 46 | } 47 | startedParsing = true; 48 | result = result * 10 + Number(s[i]); 49 | } 50 | return finalResult(result * sign); 51 | }; 52 | -------------------------------------------------------------------------------- /teemo-attacking.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} timeSeries 3 | * @param {number} duration 4 | * @return {number} 5 | */ 6 | 7 | // Runtime: 74 ms, faster than 82.76% of JavaScript online submissions for Teemo Attacking. 8 | // Memory Usage: 45.4 MB, less than 80.60% of JavaScript online submissions for Teemo Attacking. 9 | const findPoisonedDuration = (timeSeries, duration) => { 10 | let sum = 0; 11 | if (timeSeries.length === 1) { 12 | return duration; 13 | } 14 | for (let i = 1; i < timeSeries.length; i++) { 15 | const diff = timeSeries[i] - timeSeries[i - 1]; 16 | if (diff <= duration - 1) { 17 | sum += diff; 18 | } else { 19 | sum += duration; 20 | } 21 | } 22 | sum += duration; 23 | return sum; 24 | }; 25 | -------------------------------------------------------------------------------- /zigzag-conversion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {number} numRows 4 | * @return {string} 5 | */ 6 | 7 | // Runtime: 72 ms, faster than 98.91% of JavaScript online submissions for Zigzag Conversion. 8 | // Memory Usage: 46.5 MB, less than 78.40% of JavaScript online submissions for Zigzag Conversion. 9 | const convert = (s, numRows) => { 10 | let result = ""; 11 | if (numRows === 1) { 12 | return s; 13 | } 14 | for (let i = 0; i < numRows; i++) { 15 | let sumThing = (numRows - 1) * 2, 16 | firstOfPair = sumThing - i * 2, 17 | secondOfPair = sumThing - firstOfPair, 18 | index = i, 19 | alternator = 0; 20 | while (index < s.length) { 21 | result += s[index]; 22 | if (alternator % 2 === 0) { 23 | index += firstOfPair === 0 ? secondOfPair : firstOfPair; 24 | } else { 25 | index += secondOfPair === 0 ? firstOfPair : secondOfPair; 26 | } 27 | alternator++; 28 | } 29 | } 30 | return result; 31 | }; 32 | 33 | // console.log(convert("012345678", 3)); 34 | console.log(convert("ab", 1)); 35 | --------------------------------------------------------------------------------