From c8e6e41b938a51c3adba72639037f6a8a189ea9f Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Mon, 24 Feb 2025 16:05:15 -0600 Subject: [PATCH 1/9] add preliminary version --- TypeScript/Problem1.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/TypeScript/Problem1.ts b/TypeScript/Problem1.ts index e69de29..ac48fec 100644 --- a/TypeScript/Problem1.ts +++ b/TypeScript/Problem1.ts @@ -0,0 +1,41 @@ +/* +MEDIAN OF TWO SORTED ARAYS + +Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. +The overall run time complexity should be O(log (m+n)). + +Example 1: +Input: nums1 = [1,3], nums2 = [2] +Output: 2.00000 +Explanation: merged array = [1,2,3] and median is 2. + +Example 2: +Input: nums1 = [1,2], nums2 = [3,4] +Output: 2.50000 +Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. + + +Constraints: +nums1.length == m +nums2.length == n +0 <= m <= 1000 +0 <= n <= 1000 +1 <= m + n <= 2000 +-106 <= nums1[i], nums2[i] <= 106 +*/ + +// +-------------------------------- NOTA: FALTA VER SI CUMPLE CON 0(log(m+n)).--------------------------------+ + +function findMedianSortedArrays(nums1: number[], nums2: number[]): number { + let mergedArray = [...nums1, ...nums2].sort((a,b) => a-b); //junta los arrays y los ordena numéricamente de forma ascendente + let n = mergedArray.length; + + if (n % 2 === 0) { //si length es par: + return (mergedArray[n/2-1] + mergedArray[n/2])/2; //divide entre 2 la suma del extremo derecho de la primera mitad y el extremo izquierdo de la segunda mitad + } else { //si length es impar + return mergedArray[Math.floor(n/2)]; //divide entre 2 el length y lo redondea hacia abajo + } +}; + +console.log(findMedianSortedArrays([1,2], [3])); +console.log(findMedianSortedArrays([1,2], [3,4])); \ No newline at end of file From ba246eef324bed16a1434086537dfcf061513a06 Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Tue, 25 Feb 2025 11:05:22 -0600 Subject: [PATCH 2/9] add solution --- TypeScript/Problem2.ts | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/TypeScript/Problem2.ts b/TypeScript/Problem2.ts index e69de29..043c0b6 100644 --- a/TypeScript/Problem2.ts +++ b/TypeScript/Problem2.ts @@ -0,0 +1,92 @@ +/* +LRU CACHE +Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. + +Implement the LRUCache class: + +LRUCache(int capacity) Initialize the LRU cache with positive size capacity. +int get(int key) Return the value of the key if the key exists, otherwise return -1. +void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key. +The functions get and put must each run in O(1) average time complexity. + + + +Example 1: + +Input +["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] +[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] +Output +[null, null, null, 1, null, -1, null, -1, 3, 4] + +Explanation +LRUCache lRUCache = new LRUCache(2); +lRUCache.put(1, 1); // cache is {1=1} +lRUCache.put(2, 2); // cache is {1=1, 2=2} +lRUCache.get(1); // return 1 +lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3} +lRUCache.get(2); // returns -1 (not found) +lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3} +lRUCache.get(1); // return -1 (not found) +lRUCache.get(3); // return 3 +lRUCache.get(4); // return 4 + + +Constraints: + +1 <= capacity <= 3000 +0 <= key <= 10k +0 <= value <= 100k +At most 200k calls will be made to get and put. +*/ + +class LRUCache { + private capacity: number; + private cache: Map; + + constructor(capacity: number) { + if (capacity < 1 || capacity > 3000) { + throw new Error("Capacity must be between 1 and 3k"); + } + this.capacity = capacity; + this.cache = new Map(); + } + + get(key: number): number { + if (!this.cache.has(key)) {//si no existe, -1 + return -1; + } + + //En caso de sí tenerla, la mueve al final (más reciente) + const temp = this.cache.get(key)!; + this.cache.delete(key); + this.cache.set(key, temp); + return temp; + } + + put(key: number, value: number): void { + if (key < 0 || key > 10000) { + throw new Error("Key must be between 0 and 10k"); + } + + if (value < 0 || value > 100000) { + throw new Error("Value must be between 0 and 100k"); + } + + if (this.cache.has(key)) { //si ya existe, lo elimina + this.cache.delete(key); + } else if (this.cache.size == this.capacity) { //si no existía y no hay más memoria + //elimina la clave mas vieja + const [oldestKey] = this.cache.keys(); + this.cache.delete(oldestKey); + } + this.cache.set(key, value); + } +} + +/** +* Your LRUCache object will be instantiated and called as such: +* var obj = new LRUCache(capacity) +* var param_1 = obj.get(key) +* obj.put(key,value) +*/ \ No newline at end of file From 2165b704b6cfe016a841e04a42d5ee48610d29fb Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Tue, 25 Feb 2025 14:16:09 -0600 Subject: [PATCH 3/9] add problem3 solution --- TypeScript/Problem3.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/TypeScript/Problem3.ts b/TypeScript/Problem3.ts index e69de29..effb7f5 100644 --- a/TypeScript/Problem3.ts +++ b/TypeScript/Problem3.ts @@ -0,0 +1,42 @@ +/* +LONGEST SUBSTRING WITHOUT REPEATING CHARACTERS + +Given a string s, find the length of the longest substring without duplicate characters. + +Example 1: +Input: s = "abcabcbb" +Output: 3 +Explanation: The answer is "abc", with the length of 3. + +Example 2: +Input: s = "bbbbb" +Output: 1 +Explanation: The answer is "b", with the length of 1. + +Example 3: +Input: s = "pwwkew" +Output: 3 +Explanation: The answer is "wke", with the length of 3. +Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. + +Constraints: +0 <= s.length <= 50k +s consists of English letters, digits, symbols and spaces. +*/ + +function lengthOfLongestSubstring(s: string): number { + let characterIndexList: Map = new Map(); //aqui se almacenan los strings con su valor + let maxLength: number = 0; //maxima longitud histórica + let left: number = 0; //limite izquierdo indica a partir de dónde no hay caracteres repetidos + + for (let index = 0; index < s.length; index++) { + if (characterIndexList.has(s[index])) { //si el caracter ya existe en map + left = Math.max(left, characterIndexList.get(s[index])+1); //mueve left delante de la posicion repetida + } + + characterIndexList.set(s[index], index); //agrega el caracter al map. En caso de ya existir, actualiza su valor + maxLength = Math.max(maxLength, index - left + 1); //evalua qué valor es mayor: la longitud maxima registrada o la actual respecto a left + } + + return maxLength; +}; \ No newline at end of file From 3046664756b134b40d75270ec274142c00d61d57 Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Tue, 25 Feb 2025 18:57:01 -0600 Subject: [PATCH 4/9] add problem4 solution --- TypeScript/Problem4.ts | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/TypeScript/Problem4.ts b/TypeScript/Problem4.ts index e69de29..3dadc58 100644 --- a/TypeScript/Problem4.ts +++ b/TypeScript/Problem4.ts @@ -0,0 +1,55 @@ +/* +REGULAR EXPRESSION MATCHING + +Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where: +'.' Matches any single character.​​​​ +'*' Matches zero or more of the preceding element. +The matching should cover the entire input string (not partial). + +Example 1: +Input: s = "aa", p = "a" +Output: false +Explanation: "a" does not match the entire string "aa". + +Example 2: +Input: s = "aa", p = "a*" +Output: true +Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". + +Example 3: +Input: s = "ab", p = ".*" +Output: true +Explanation: ".*" means "zero or more (*) of any character (.)". + +Constraints: +1 <= s.length <= 20 +1 <= p.length <= 20 +s contains only lowercase English letters. +p contains only lowercase English letters, '.', and '*'. +It is guaranteed for each appearance of the character '*', there will be a previous valid character to match. +*/ + +function isMatch(s: string, p: string): boolean { + let lastCharacter: string = ''; + let flag: boolean = true; //indica si el caracter es o no es coincidente + + for (let index = 0; index < s.length; index++) { + if (!flag) { + return flag; //termina el proceso en false + } + + if (p[index] === "." && p[index+1] === "*") { //condicion unica para p = .* debido a que ese patron siempre será correcto + return true; + } + + if (p[index] === "." || s[index] === p[index]) { //si el index de p es "." ó ambos inputs coinciden + lastCharacter = p[index]; //guarda el index actual de p + flag = true; //es valido + } else if (p[index] === "*" && lastCharacter === s[index]) { //evalúa si el string actual de "s" coincide con el anterior de p = * + flag = true; + } else { + flag = false; + } + } + return flag; +}; \ No newline at end of file From 74553513517bb37609ef2253c138ec006767f067 Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Fri, 28 Feb 2025 13:34:22 -0600 Subject: [PATCH 5/9] remove unnecessary comments --- TypeScript/Problem1.ts | 22 ++-------------------- TypeScript/Problem2.ts | 42 +++--------------------------------------- TypeScript/Problem3.ts | 24 ++---------------------- TypeScript/Problem4.ts | 25 ++----------------------- 4 files changed, 9 insertions(+), 104 deletions(-) diff --git a/TypeScript/Problem1.ts b/TypeScript/Problem1.ts index ac48fec..3df686b 100644 --- a/TypeScript/Problem1.ts +++ b/TypeScript/Problem1.ts @@ -1,27 +1,9 @@ /* -MEDIAN OF TWO SORTED ARAYS +4. MEDIAN OF TWO SORTED ARAYS Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). - -Example 1: -Input: nums1 = [1,3], nums2 = [2] -Output: 2.00000 -Explanation: merged array = [1,2,3] and median is 2. - -Example 2: -Input: nums1 = [1,2], nums2 = [3,4] -Output: 2.50000 -Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. - - -Constraints: -nums1.length == m -nums2.length == n -0 <= m <= 1000 -0 <= n <= 1000 -1 <= m + n <= 2000 --106 <= nums1[i], nums2[i] <= 106 +Go to LeetCode and look for the problem #4, and read the examples for a better understanding. */ // +-------------------------------- NOTA: FALTA VER SI CUMPLE CON 0(log(m+n)).--------------------------------+ diff --git a/TypeScript/Problem2.ts b/TypeScript/Problem2.ts index 043c0b6..fcce29e 100644 --- a/TypeScript/Problem2.ts +++ b/TypeScript/Problem2.ts @@ -1,43 +1,7 @@ /* -LRU CACHE +146. LRU CACHE Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. - -Implement the LRUCache class: - -LRUCache(int capacity) Initialize the LRU cache with positive size capacity. -int get(int key) Return the value of the key if the key exists, otherwise return -1. -void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key. -The functions get and put must each run in O(1) average time complexity. - - - -Example 1: - -Input -["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] -[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] -Output -[null, null, null, 1, null, -1, null, -1, 3, 4] - -Explanation -LRUCache lRUCache = new LRUCache(2); -lRUCache.put(1, 1); // cache is {1=1} -lRUCache.put(2, 2); // cache is {1=1, 2=2} -lRUCache.get(1); // return 1 -lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3} -lRUCache.get(2); // returns -1 (not found) -lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3} -lRUCache.get(1); // return -1 (not found) -lRUCache.get(3); // return 3 -lRUCache.get(4); // return 4 - - -Constraints: - -1 <= capacity <= 3000 -0 <= key <= 10k -0 <= value <= 100k -At most 200k calls will be made to get and put. +Go to LeetCodde and look for the problem #146, and read the instructions to understand this better. */ class LRUCache { @@ -80,7 +44,7 @@ class LRUCache { const [oldestKey] = this.cache.keys(); this.cache.delete(oldestKey); } - this.cache.set(key, value); + this.cache.set(key, value); //vuelve a insertar la key preexistente para actualizarla al lugar mas reciente } } diff --git a/TypeScript/Problem3.ts b/TypeScript/Problem3.ts index effb7f5..c53e379 100644 --- a/TypeScript/Problem3.ts +++ b/TypeScript/Problem3.ts @@ -1,27 +1,7 @@ /* -LONGEST SUBSTRING WITHOUT REPEATING CHARACTERS - +3. LONGEST SUBSTRING WITHOUT REPEATING CHARACTERS Given a string s, find the length of the longest substring without duplicate characters. - -Example 1: -Input: s = "abcabcbb" -Output: 3 -Explanation: The answer is "abc", with the length of 3. - -Example 2: -Input: s = "bbbbb" -Output: 1 -Explanation: The answer is "b", with the length of 1. - -Example 3: -Input: s = "pwwkew" -Output: 3 -Explanation: The answer is "wke", with the length of 3. -Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. - -Constraints: -0 <= s.length <= 50k -s consists of English letters, digits, symbols and spaces. +Go to LeetCode and look for the problem #3, and read the instructions for a better understanding. */ function lengthOfLongestSubstring(s: string): number { diff --git a/TypeScript/Problem4.ts b/TypeScript/Problem4.ts index 3dadc58..69832e2 100644 --- a/TypeScript/Problem4.ts +++ b/TypeScript/Problem4.ts @@ -1,32 +1,11 @@ /* -REGULAR EXPRESSION MATCHING - +10. REGULAR EXPRESSION MATCHING Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where: '.' Matches any single character.​​​​ '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). -Example 1: -Input: s = "aa", p = "a" -Output: false -Explanation: "a" does not match the entire string "aa". - -Example 2: -Input: s = "aa", p = "a*" -Output: true -Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". - -Example 3: -Input: s = "ab", p = ".*" -Output: true -Explanation: ".*" means "zero or more (*) of any character (.)". - -Constraints: -1 <= s.length <= 20 -1 <= p.length <= 20 -s contains only lowercase English letters. -p contains only lowercase English letters, '.', and '*'. -It is guaranteed for each appearance of the character '*', there will be a previous valid character to match. +Go to LeetCode and look for the problem #10. Read the examples for a better understanding. */ function isMatch(s: string, p: string): boolean { From f03edbf50a1a0ff3c29d583546ac9b7807783faa Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Fri, 28 Feb 2025 16:18:07 -0600 Subject: [PATCH 6/9] Problem[3] add non-null symbol --- TypeScript/Problem3.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TypeScript/Problem3.ts b/TypeScript/Problem3.ts index c53e379..6db9040 100644 --- a/TypeScript/Problem3.ts +++ b/TypeScript/Problem3.ts @@ -11,7 +11,7 @@ function lengthOfLongestSubstring(s: string): number { for (let index = 0; index < s.length; index++) { if (characterIndexList.has(s[index])) { //si el caracter ya existe en map - left = Math.max(left, characterIndexList.get(s[index])+1); //mueve left delante de la posicion repetida + left = Math.max(left, characterIndexList.get(s[index])!+1); //mueve left delante de la posicion repetida } characterIndexList.set(s[index], index); //agrega el caracter al map. En caso de ya existir, actualiza su valor From 3a9a48296461ba73285f394a325b721b0fb422c0 Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Fri, 28 Feb 2025 20:22:12 -0600 Subject: [PATCH 7/9] Problem[4]: add Dynamic Programming solution --- TypeScript/Problem4.ts | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/TypeScript/Problem4.ts b/TypeScript/Problem4.ts index 69832e2..a51fb04 100644 --- a/TypeScript/Problem4.ts +++ b/TypeScript/Problem4.ts @@ -9,26 +9,29 @@ Go to LeetCode and look for the problem #10. Read the examples for a better unde */ function isMatch(s: string, p: string): boolean { - let lastCharacter: string = ''; - let flag: boolean = true; //indica si el caracter es o no es coincidente + const dp: boolean[][] = Array(s.length + 1).fill(null).map(() => Array(p.length + 1).fill(false)); //crea matriz en false + dp[0][0] = true; //true porque las cadenas al inicio coinciden al estar vacias - for (let index = 0; index < s.length; index++) { - if (!flag) { - return flag; //termina el proceso en false + for (let j = 2; j <= p.length; j += 2) { //maneja patrones como "a*" o ".*" al inicio + if (p[j - 1] === '*') { + dp[0][j] = dp[0][j - 2]; } + } - if (p[index] === "." && p[index+1] === "*") { //condicion unica para p = .* debido a que ese patron siempre será correcto - return true; - } - - if (p[index] === "." || s[index] === p[index]) { //si el index de p es "." ó ambos inputs coinciden - lastCharacter = p[index]; //guarda el index actual de p - flag = true; //es valido - } else if (p[index] === "*" && lastCharacter === s[index]) { //evalúa si el string actual de "s" coincide con el anterior de p = * - flag = true; - } else { - flag = false; + //compara cada caracter de la cadena con el patron + for (let i = 1; i <= s.length; i++) { + for (let j = 1; j <= p.length; j++) { + if (p[j - 1] === s[i - 1] || p[j - 1] === '.') { //si coinciden exactamente o es "." + dp[i][j] = dp[i - 1][j - 1]; + } else if (p[j - 1] === '*') { //en caso de encontrar "*" + dp[i][j] = dp[i][j - 2]; //opcion 1: no se usa el caracter previo + + if (p[j - 2] === s[i - 1] || p[j - 2] === '.') { + dp[i][j] = dp[i][j] || dp[i - 1][j]; //opcion 2: se usa el carácter previo si coincide con el actual de s + } + } } } - return flag; -}; \ No newline at end of file + + return dp[s.length][p.length]; //se comparan las cadenas +} \ No newline at end of file From 200d247e8308688a2fd187b84ed601a7da07b4af Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Mon, 3 Mar 2025 10:13:18 -0600 Subject: [PATCH 8/9] Problem[1]: add alternative solution --- TypeScript/Problem1.ts | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/TypeScript/Problem1.ts b/TypeScript/Problem1.ts index 3df686b..426e82a 100644 --- a/TypeScript/Problem1.ts +++ b/TypeScript/Problem1.ts @@ -6,18 +6,26 @@ The overall run time complexity should be O(log (m+n)). Go to LeetCode and look for the problem #4, and read the examples for a better understanding. */ -// +-------------------------------- NOTA: FALTA VER SI CUMPLE CON 0(log(m+n)).--------------------------------+ - function findMedianSortedArrays(nums1: number[], nums2: number[]): number { - let mergedArray = [...nums1, ...nums2].sort((a,b) => a-b); //junta los arrays y los ordena numéricamente de forma ascendente - let n = mergedArray.length; + const totalLength = nums1.length + nums2.length; + const isEven = totalLength % 2 === 0; + const medianIndex = Math.floor(totalLength / 2); + + let i = 0; + let j = 0; + let current = 0; + let previous = 0; - if (n % 2 === 0) { //si length es par: - return (mergedArray[n/2-1] + mergedArray[n/2])/2; //divide entre 2 la suma del extremo derecho de la primera mitad y el extremo izquierdo de la segunda mitad - } else { //si length es impar - return mergedArray[Math.floor(n/2)]; //divide entre 2 el length y lo redondea hacia abajo + for (let k = 0; k <= medianIndex; k++) { + previous = current; + if (i < nums1.length && (j >= nums2.length || nums1[i] < nums2[j])) { + current = nums1[i]; + i++; + } else { + current = nums2[j]; + j++; } -}; + } -console.log(findMedianSortedArrays([1,2], [3])); -console.log(findMedianSortedArrays([1,2], [3,4])); \ No newline at end of file + return isEven ? (previous + current) / 2 : current; +}; \ No newline at end of file From b2a3678beaf335ce7723c91b0138502b3b5306b9 Mon Sep 17 00:00:00 2001 From: SamBSalgado Date: Mon, 3 Mar 2025 10:57:31 -0600 Subject: [PATCH 9/9] Problem[1]: add comments --- TypeScript/Problem1.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/TypeScript/Problem1.ts b/TypeScript/Problem1.ts index 426e82a..0bcd39c 100644 --- a/TypeScript/Problem1.ts +++ b/TypeScript/Problem1.ts @@ -16,16 +16,18 @@ function findMedianSortedArrays(nums1: number[], nums2: number[]): number { let current = 0; let previous = 0; - for (let k = 0; k <= medianIndex; k++) { - previous = current; - if (i < nums1.length && (j >= nums2.length || nums1[i] < nums2[j])) { - current = nums1[i]; - i++; + for (let k = 0; k <= medianIndex; k++) { // itera hasta alcanzar ell índice del elemento medio + previous = current; // guarda el valor actual en previous + if (i < nums1.length && (j >= nums2.length || nums1[i] < nums2[j])) { // compara los elementos de los arrays y selecciona el menor + current = nums1[i]; // asigna el index de nums1 a current + i++; // y avanza el index i } else { - current = nums2[j]; - j++; + current = nums2[j]; // asigna el valor de nums2 a current + j++; // y avanza index j } } - return isEven ? (previous + current) / 2 : current; + return isEven ? (previous + current) / 2 : current; // si isEven resulta true, devuelve la division + // entre 2 de la suma de previous y current. + // Si isEven es false, devuelve current. }; \ No newline at end of file