diff --git a/javascript/LeetCode/Array/1200.js b/javascript/LeetCode/Array/1200.js new file mode 100644 index 0000000..14409e1 --- /dev/null +++ b/javascript/LeetCode/Array/1200.js @@ -0,0 +1,31 @@ +/** + * 1200. Minimum Absolute Difference + * + * 給一個無重複元素的數字陣列,找出兩個元素間相差最小的元素並將它們歸類為一組,回傳陣列為二維陣列,必須遞增方式排序[a,b] + * a < b + * b - a = 每組最小相等值 + * + * @param {number[]} arr + * @return {number[][]} + */ +var minimumAbsDifference = function(arr) { + arr.sort((a,b) => a - b); + let min = Infinity; + let res = []; + for(let i = 1;i < arr.length;++i) { + let diff = arr[i] - arr[i-1]; + if(diff < min){ + min = diff; + res = [i - 1]; + }else if(diff === min){ + res.push(i - 1); + } + } + return res.map(i => [arr[i], arr[i + 1]]); +}; +// let nums = [4,2,1,3]; +// Output: [[1,2],[2,3],[3,4]] +// Explanation: The minimum absolute difference is 1. List all pairs with difference equal to 1 in ascending order. +let nums = [-17,46,63,81,-101,-91,121,-2,112,-15,-65,-96,6,-139]; +// [[-17,15]] +console.log(minimumAbsDifference(nums)); \ No newline at end of file diff --git a/javascript/LeetCode/Array/2974.js b/javascript/LeetCode/Array/2974.js new file mode 100644 index 0000000..ae69ec9 --- /dev/null +++ b/javascript/LeetCode/Array/2974.js @@ -0,0 +1,38 @@ +/** + * 2974. Minimum Number Game + * + * nums.length = even(偶數),每一輪選手(Alice and Bob )皆須: + * 第一步,Alice先從陣列中移除最小的元素一次,之後換Bob做同樣的事情(移除第一小&第二小的元素) + * 第二步,Bob將移除的元素加進空陣列arr中,再換Alice做同樣的事情(添加第二小元素&第一小元素) + * 重複上述步驟直到nums變成空陣列為止,回傳最終的arr + * + * @param {number[]} nums + * @return {number[]} arr + */ +var numberGame = function(nums) { + let arr = []; + nums.sort((a,b) => a - b); + // 兩個兩個比較並交換 + for(let i = 0;i < nums.length;i+=2) { + // 有可能有同樣的元素,所以得<= + if(nums[i] <= nums[i+1]){ + let temp = nums[i]; + arr[i] = nums[i + 1]; + arr[i + 1] = temp; + } + } + return arr; + + // solution 2. + // nums.sort((a,b) => a - b); + // // 兩個兩個比較並交換 + // for(let i = 0;i < nums.length;i+=2) { + // [nums[i],nums[i+1]] = [nums[i+1],nums[i]] + // } + // return nums; +}; +let nums = [5,4,2,3]; +// Output: [3,2,5,4] +// Explanation: In round one, first Alice removes 2 and then Bob removes 3. Then in arr firstly Bob appends 3 and then Alice appends 2. So arr = [3,2]. +// At the begining of round two, nums = [5,4]. Now, first Alice removes 4 and then Bob removes 5. Then both append in arr which becomes [3,2,5,4]. +console.log(numberGame(nums)); \ No newline at end of file diff --git a/javascript/LeetCode/Array/3314.js b/javascript/LeetCode/Array/3314.js new file mode 100644 index 0000000..0dfc5a2 --- /dev/null +++ b/javascript/LeetCode/Array/3314.js @@ -0,0 +1,34 @@ +/** + * 3314. Construct the Minimum Bitwise Array I + * + * prime number = 1 & itself. + * ans[i] 與 ans[i] + 1 的位元或運算等於 nums[i],即 ans[i] OR (ans[i] + 1) == nums[i]。 + * + * @param {number[]} nums + * @return {number[]} + */ +var minBitwiseArray = function(nums) { + let ans = new Array(nums.length); + + for(let i = 0;i < nums.length;++i) { + let maybe = -1; + for(let j = 1;j < nums[i];++j) { + if((j | (j + 1)) === nums[i]){ + maybe = j; + break; + } + } + ans[i] = maybe; + } + return ans; +}; +let nums = [2,3,5,7]; +/** + * [-1,1,4,3] +Explanation: +For i = 0, as there is no value for ans[0] that satisfies ans[0] OR (ans[0] + 1) = 2, so ans[0] = -1. +For i = 1, the smallest ans[1] that satisfies ans[1] OR (ans[1] + 1) = 3 is 1, because 1 OR (1 + 1) = 3. +For i = 2, the smallest ans[2] that satisfies ans[2] OR (ans[2] + 1) = 5 is 4, because 4 OR (4 + 1) = 5. +For i = 3, the smallest ans[3] that satisfies ans[3] OR (ans[3] + 1) = 7 is 3, because 3 OR (3 + 1) = 7. + */ +console.log(minBitwiseArray(nums)); \ No newline at end of file diff --git a/javascript/LeetCode/Array/3379.js b/javascript/LeetCode/Array/3379.js new file mode 100644 index 0000000..a70903f --- /dev/null +++ b/javascript/LeetCode/Array/3379.js @@ -0,0 +1,30 @@ +/** + * 3379. Transformed Array + * + * nums is circular,所以不管往左或往右,都有可能回到原點 + * + * nums[i] > 0 => index i往右移nums[i]步至nums[i]的位置,並將result[i]設成index i值 + * nums[i] < 0 => index i往左移nums[i]步至abs(nums[i])的位置,並將result[i]設成index i值 + * nums[i] === 0 => result[i] = nums[i] + * + * @param {number[]} nums + * @return {number[]} + */ +var constructTransformedArray = function(nums) { + let res = []; + for(let i = 0;i < nums.length;++i) { + // 計算要往左或右,在哪個index + res[i] = nums[((i + nums[i]) % nums.length + nums.length) % nums.length]; + } + return res; +}; +let nums = [3,-2,1,1]; +/* +Output: [1,1,1,3] +Explanation: +For nums[0] that is equal to 3, If we move 3 steps to right, we reach nums[3]. So result[0] should be 1. +For nums[1] that is equal to -2, If we move 2 steps to left, we reach nums[3]. So result[1] should be 1. +For nums[2] that is equal to 1, If we move 1 step to right, we reach nums[3]. So result[2] should be 1. +For nums[3] that is equal to 1, If we move 1 step to right, we reach nums[0]. So result[3] should be 3. +*/ +console.log(constructTransformedArray(nums)); \ No newline at end of file diff --git a/javascript/LeetCode/Array/3634.js b/javascript/LeetCode/Array/3634.js new file mode 100644 index 0000000..627394c --- /dev/null +++ b/javascript/LeetCode/Array/3634.js @@ -0,0 +1,28 @@ +/** + * 3634. Minimum Removals to Balance Array + * + * balanced條件 = 最大元素 <= 最小元素 * k值 + * 可移除任一元素,回傳要移除幾個元素才能達成balanced這條件 + * + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var minRemoval = function(nums, k) { + nums.sort((a,b) => a - b); + let i = 0; + let count = 0; + for(let j = 0;j < nums.length;++j) { + // 2 pointers.i & j + while(nums[j] > nums[i] * k){ + i++; + } + count = Math.max(count, j - i + 1); + } + return nums.length - count; +}; +let nums = [1,6,2,9], k = 3; +// 2 +// Remove nums[0] = 1 and nums[3] = 9 to get nums = [6, 2]. +// Now max = 6, min = 2 and max <= min * k as 6 <= 2 * 3. Thus, the answer is 2. +console.log(minRemoval(nums,k)); \ No newline at end of file diff --git a/javascript/LeetCode/Array/3736.js b/javascript/LeetCode/Array/3736.js new file mode 100644 index 0000000..f7f889e --- /dev/null +++ b/javascript/LeetCode/Array/3736.js @@ -0,0 +1,29 @@ +/** + * 3736. Minimum Moves to Equal Array Elements III + * + * 參數為數值陣列,在一次操作中可將任一元素+1 + * 回傳須移動幾次才能將所有元素都變得一樣 + * + * @param {number[]} nums + * @return {number} + */ +var minMoves = function(nums) { + // 要先知道nums中最大值是多少,這樣就能知道其他元素跟最大值差多少 + let count = 0; + let maxEle = Math.max(...nums); + for(let i = 0;i < nums.length;++i) { + count += Math.abs(maxEle - nums[i]); + } + return count; +}; +let nums = [2,1,3]; +/* +Output: 3 +Explanation: +To make all elements equal: +Increase nums[0] = 2 by 1 to make it 3. +Increase nums[1] = 1 by 1 to make it 2. +Increase nums[1] = 2 by 1 to make it 3. +Now, all elements of nums are equal to 3. The minimum total moves is 3. +*/ +console.log(minMoves(nums)) \ No newline at end of file diff --git a/javascript/LeetCode/Array/3838.js b/javascript/LeetCode/Array/3838.js new file mode 100644 index 0000000..f4101cd --- /dev/null +++ b/javascript/LeetCode/Array/3838.js @@ -0,0 +1,92 @@ +/** + * 3838. Weighted Word Mapping + * + * 0 = z;1 = y;2 = x....;25 = a,26個字母倒著 + * 將每個元素字母重量加總後%26得出的A值,將A值與26個字母倒著的value做比對,取對應的key並以字串回傳 + * + * @param {string[]} words + * @param {number[]} weights + * @return {string} + */ +var mapWordWeights = function(words, weights) { + // 解法1,使用map + // 可能遇到的狀況:key(字母)、value(數字)重複出現 + let alp = generateAlphabet(); + let sumWeights = []; + + for (const element of words) { + let countLen = 0; + for(let i = 0;i < element.length;++i) { + countLen += weights[element.charCodeAt(i) - 'a'.charCodeAt()] + } + // modulo 26 + sumWeights.push(countLen % 26); + } + // 方法1 + // const result = sumWeights.map(num => { + // const found = [...alp.entries()] + // .find(([key, value]) => value === num); + // return found ? found[0] : null; + // }); + + // 方法2 反向 Map + const reverseMap = new Map( + [...alp.entries()].map(([k, v]) => [v, k]) + ); + + const result = sumWeights.map(num => reverseMap.get(num) ?? null); + + return result.join("") + + + /** + * 產生26個英文字母 + * a = 26,b = 25 .... + * @returns obj + */ + function generateAlphabet(){ + let start = "a"; + let end = "z"; + let alp = new Map(); + let range = 25; + let i = start.charCodeAt(0), j = end.charCodeAt(0); + for (; i <= j; ++i) { + alp.set(String.fromCharCode(i),range--); + } + return alp; + } + +}; + +/** + * 解法2。沒有另寫涵式產生26個英文字母 + * 此法較快 + * + * @param {*} words + * @param {*} weights + * @returns + */ +var mapWordWeights2 = function(words, weights) { + let sumWeights = []; + + for (const element of words) { + let countLen = 0; + for(let i = 0;i < element.length;++i) { + countLen += weights[element.charCodeAt(i) - 'a'.charCodeAt()] + } + // String.fromCharCode(ascii code) => ascii code to char. + sumWeights.push(String.fromCharCode('z'.charCodeAt() - countLen % 26)); + } + return sumWeights.join("") +} +let list = ["abcd","def","xyz"], weights = [5,3,12,14,1,2,3,2,10,6,6,9,7,8,7,10,8,9,6,9,9,8,3,7,7,2]; +/* +Output: "rij" +Explanation: +The weight of "abcd" is 5 + 3 + 12 + 14 = 34. The result modulo 26 is 34 % 26 = 8, which maps to 'r'. +The weight of "def" is 14 + 1 + 2 = 17. The result modulo 26 is 17 % 26 = 17, which maps to 'i'. +The weight of "xyz" is 7 + 7 + 2 = 16. The result modulo 26 is 16 % 26 = 16, which maps to 'j'. +Thus, the string formed by concatenating the mapped characters is "rij". +*/ +console.log(mapWordWeights(list,weights)); +console.log(mapWordWeights2(list,weights)); \ No newline at end of file diff --git a/javascript/LeetCode/String/345.js b/javascript/LeetCode/String/345.js new file mode 100644 index 0000000..7ee642b --- /dev/null +++ b/javascript/LeetCode/String/345.js @@ -0,0 +1,37 @@ +/** + * 345. Reverse Vowels of a String + * + * 找出所有母音(不分大小寫),其餘子音維持原位,唯獨反轉母音 + * @param {string} s + * @return {string} + */ +var reverseVowels = function(s) { + let vowels = 'aeiouAEIOU'; + let splitS = s.split(""); + let i = 0, j = s.length - 1; + while(i < j){ + while(i < j && vowels.indexOf(splitS[i]) == -1){ + i++; + } + while(i < j && vowels.indexOf(splitS[j]) == -1) { + j--; + } + // 交換母音 + let chars = splitS[i]; + splitS[i] = splitS[j]; + splitS[j] = chars; + + // 2 pointers + i++; + j--; + } + return splitS.join(""); +}; +let s = "IceCreAm"; +/** + * Output: "AceCreIm" + * Explanation: + * The vowels in s are ['I', 'e', 'e', 'A']. On reversing the vowels, s becomes "AceCreIm". + * + */ +console.log(reverseVowels(s)); \ No newline at end of file diff --git a/javascript/LeetCode/String/3856.js b/javascript/LeetCode/String/3856.js new file mode 100644 index 0000000..330feb9 --- /dev/null +++ b/javascript/LeetCode/String/3856.js @@ -0,0 +1,25 @@ +/** + * 3856. Trim Trailing Vowels + * + * 移除s中後半部的母音 + * + * @param {string} s + * @return {string} + */ +var trimTrailingVowels = function(s) { + /** + * 從後面開始檢查每個字元是否是母音,若是,則移除並繼續往前找直到非母音為止 + */ + + let splitS = s.split("").reverse(); + let i = 0; + while(splitS[i] === 'a' || splitS[i] === 'e' || splitS[i] === 'i' || splitS[i] === 'o' || splitS[i] === 'u'){ + splitS.shift(); + } + return splitS.reverse().join(""); +}; +// let s = "idea"; +//"id" +// let s = "day"; +let s = "aeiou"; +console.log(trimTrailingVowels(s)); \ No newline at end of file diff --git a/javascript/index.js b/javascript/index.js index 1218a05..f11eb90 100644 --- a/javascript/index.js +++ b/javascript/index.js @@ -3,6 +3,7 @@ import { format } from 'node:path'; import {ExecutionTimer} from './time.js'; import assert from 'node:assert/strict'; import { count } from 'node:console'; +import { lchown } from 'node:fs'; /* 22. Generate Parentheses @@ -1161,42 +1162,120 @@ var specialTriplets = function(nums) { // console.log(specialTriplets(nums)); - /** - * 345. Reverse Vowels of a String + * Alphabet symmetry * - * 找出所有母音(不分大小寫),其餘子音維持原位,唯獨反轉母音 - * @param {string} s - * @return {string} - */ -var reverseVowels = function(s) { - let vowels = ["a","e","i","o","u","A","E","I","O","U"]; - let splitS = s.split(""); - // 2 pointer? - let j = splitS.length - 1,i = 0; - while(i < j){ - if(!vowels.includes(splitS[i],i)){ - i++; + * 參數為有英文字母但大小寫不一定的陣列,依據26個字母順序來看:a - z /A - Z = 1 ~ 26,以陣列型態回傳元素字母與26個字母對應且字母順序正確的有幾個 + * + * EG.["abode","ABc","xyzD"]) = [4, 3, 1] + * 說明: + * a,b = 在26個順序中是1,2 且在這也是1,2; + * d,e = 在26個順序中是4,5 且在這也是4,5 => 總共有4個字母出現順序正確 +*/ +function solve(arr){ + // 元素字母有大小寫 + // 同一元素字串可能會有重複的字母 + let letterObj = generateAlphabet(); + // console.log(letterObj) + let map = new Map(); + // let set = new Set(); + let result = []; + let count = 0; + let baseASCIICode = "A".charCodeAt(); + for(const letter of arr){ + let element = letter.toLowerCase() + for(let i = 0;i < element.length;++i) { + let ascii = element.charCodeAt(i); + if(ascii+1 === element.charAt(i)){ + count++; continue; + } - if(!vowels.includes(splitS[j],j)){ - j--; - continue; + if(count === element.length){ + count = 0; + } + result.push(count); + } + console.log(result) + // let set = new Set( [...letter.toLowerCase().split("")].join('')) + // console.log([...set].join("")) + // let toStrFromSet = [...set].join(""); + + // for(let i = 0;i < toStrFromSet.length;++i) { + // console.log(toStrFromSet[i]); + + // } + } + + /** + * 產生26個英文字母 + * a = 26,b = 25 .... + * @returns obj + */ + function generateAlphabet(){ + let start = "a"; + let end = "z"; + let alp = new Map(); + let range = 26; + let i = start.charCodeAt(0), j = end.charCodeAt(0); + for (; i <= j; ++i) { + // alp[String.fromCharCode(i)] = range--; + alp.set(String.fromCharCode(i),range--); } - let char = splitS[i]; - splitS[i] = splitS[j]; - splitS[j] = char; + return alp; + } + + // console.log(letterObj) +}; +let arr = ["IAMDEFANDJKL","thedefgh","xyzDEFghijabc"]; +// describe("Basic tests", () => { +// it("Fixed tests", () => { +// assert.deepEqual(solve(["abode","ABc","xyzD"]),[4,3,1]); +// assert.deepEqual(solve(["abide","ABc","xyz"]),[4,3,0]); +// assert.deepEqual(solve(["IAMDEFANDJKL","thedefgh","xyzDEFghijabc"]),[6, 5, 7]); +// assert.deepEqual(solve(["encode","abc","xyzD","ABmD"]),[1, 3, 1, 3]); +// }); +// }); +// console.log(solve(arr)) + +var minRemoval = function(nums, k) { + nums.sort((a,b) => a - b); + let i = 0; + let count = 0; + for(let j = 0;j < nums.length;++j) { + // 2 pointers.i & j + while(nums[j] > nums[i] * k){ i++; - j--; } - return splitS.join(""); + count = Math.max(count, j - i + 1); + } + return nums.length - count; }; -let s = "IceCreAm"; +// let nums = [1,6,2,9], k = 3; +// 2 +// Remove nums[0] = 1 and nums[3] = 9 to get nums = [6, 2]. +// Now max = 6, min = 2 and max <= min * k as 6 <= 2 * 3. Thus, the answer is 2. +// console.log(minRemoval(nums,k)); + + /** - * Output: "AceCreIm" - * Explanation: - * The vowels in s are ['I', 'e', 'e', 'A']. On reversing the vowels, s becomes "AceCreIm". + * 1653. Minimum Deletions to Make String Balanced * + * 參數s中只有'a' & 'b'這兩個字母。 + * 刪除任一字母使s balanced,若不存在一對index (i,j) 使得 i < j 且 s[i] = 'b' 且 s[j] = 'a',則s 是balanced。 + * 回傳最小須刪除幾次才能使s balanced + * + * @param {string} s + * @return {number} */ -// console.log(reverseVowels(s)); +var minimumDeletions = function(s) { + +}; +// let s = "aababbab"; +/*Output: 2 +Explanation: You can either: +Delete the characters at 0-indexed positions 2 and 6 ("aababbab" -> "aaabbb"), or +Delete the characters at 0-indexed positions 3 and 6 ("aababbab" -> "aabbbb"). +*/ +// console.log(minimumDeletions(s)); diff --git a/javascript/nodejs/app.js b/javascript/nodejs/app.js deleted file mode 100644 index 02003ad..0000000 --- a/javascript/nodejs/app.js +++ /dev/null @@ -1,12 +0,0 @@ -const { createServer } = require('node:http'); -const hostname = '127.0.0.1'; -const port = 3000; - -const server = createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); \ No newline at end of file diff --git a/javascript/nodejs/app.mjs b/javascript/nodejs/app.mjs new file mode 100644 index 0000000..17a33ca --- /dev/null +++ b/javascript/nodejs/app.mjs @@ -0,0 +1,24 @@ +// const { createServer } = require('node:http'); +// const hostname = '127.0.0.1'; +// const port = 3000; + +// const server = createServer((req, res) => { +// res.statusCode = 200; +// res.setHeader('Content-Type', 'text/plain'); +// res.end('Hello World'); +// }); +// server.listen(port, hostname, () => { +// console.log(`Server running at http://${hostname}:${port}/`); +// }); + +// ESM +import http from "http"; + +const server = http.createServer((req, res) => { + res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" }); + res.end("Hello Node Server 👋 (ESM)"); +}); + +server.listen(3000, () => { + console.log("Server running at http://localhost:3000"); +}); diff --git a/python/lo.py b/python/lo.py new file mode 100644 index 0000000..ca363db --- /dev/null +++ b/python/lo.py @@ -0,0 +1,47 @@ +# import pandas as pd + +# # 建立範例資料 (第 114000079 期到 115000007 期) +# data = { +# "期別": ["114000079","114000080","114000081","114000082","114000083", +# "115000001","115000002","115000003","115000004","115000005","115000006","115000007"], +# "開獎日期": ["2025-10-02","2025-10-06","2025-10-09","2025-10-13","2025-10-16", +# "2026-01-01","2026-01-05","2026-01-08","2026-01-12","2026-01-15","2026-01-19","2026-01-22"], +# "第一區號碼": [ +# [3,5,12,24,27,30],[5,6,9,14,15,37],[1,6,11,20,34,35], +# [2,8,12,18,28,33],[4,9,16,21,25,36],[7,14,22,23,31,35], +# [11,14,19,25,34,37],[7,17,25,26,27,33],[1,9,14,17,33,38], +# [8,10,16,26,31,38],[10,16,20,23,35,37],[11,17,29,30,34,35] +# ], +# "第二區": [7,5,8,3,4,1,4,3,3,5,5,6], +# "備註": ["頭獎","無頭獎","無頭獎","無頭獎","無頭獎","無頭獎", +# "無頭獎","無頭獎","無頭獎","無頭獎","無頭獎","無頭獎"] +# } + +# df = pd.DataFrame(data) + +# # 計算第一區 01~38 次數與頻率 +# freq_zone1 = pd.DataFrame({"號碼": list(range(1,39))}) +# freq_zone1["出現次數"] = freq_zone1["號碼"].apply(lambda x: sum(df["第一區號碼"].apply(lambda y: x in y))) +# freq_zone1["頻率(%)"] = freq_zone1["出現次數"]/freq_zone1["出現次數"].sum()*100 + +# # 計算第二區 01~08 次數與頻率 +# freq_zone2 = pd.DataFrame({"號碼": list(range(1,9))}) +# freq_zone2["出現次數"] = freq_zone2["號碼"].apply(lambda x: sum(df["第二區"]==x)) +# freq_zone2["頻率(%)"] = freq_zone2["出現次數"]/freq_zone2["出現次數"].sum()*100 + +# # 將資料寫入 Excel,多 sheet +# with pd.ExcelWriter("威力彩分析_114000079_115000007.xlsx") as writer: +# df.to_excel(writer, sheet_name="RawData", index=False) +# freq_zone1.to_excel(writer, sheet_name="Freq_Zone1", index=False) +# freq_zone2.to_excel(writer, sheet_name="Freq_Zone2", index=False) + +# print("Excel 檔案已生成:威力彩分析_114000079_115000007.xlsx") + + +import random + +# 模擬一次威力彩開獎 +main_numbers = random.sample(range(1, 39), 6) # 從1~38中抽6個 +special_number = random.randint(1, 8) # 從1~8中抽1個 +print("第一區:", sorted(main_numbers)) +print("特別號:", special_number)