From e41d6ac7ebfabbbd91c620aa9607c29aff2b7560 Mon Sep 17 00:00:00 2001 From: Yang Libin Date: Sat, 7 Oct 2023 11:23:48 +0000 Subject: [PATCH] feat: add solutions to lc problems: No.1817,1826,1833,1835,1836 * No.1817.Find the Users Active Minutes * No.1826.Faulty Sensor * No.1833.Maximum Ice Cream Bars * No.1835.Find XOR Sum of All Pairs Bitwise AND * No.1836.Remove Duplicates From an Unsorted Linked List --- .../README.md | 21 +++++++++- .../README_EN.md | 25 ++++++++++++ .../Solution.ts | 14 +++++++ .../README.md | 8 ++-- .../1800-1899/1826.Faulty Sensor/README.md | 25 ++++++++++++ .../1800-1899/1826.Faulty Sensor/README_EN.md | 25 ++++++++++++ .../1800-1899/1826.Faulty Sensor/Solution.ts | 20 ++++++++++ .../1833.Maximum Ice Cream Bars/README.md | 16 ++++++++ .../1833.Maximum Ice Cream Bars/README_EN.md | 24 +++++++++++- .../1833.Maximum Ice Cream Bars/Solution.ts | 11 ++++++ .../README.md | 16 ++++++-- .../README_EN.md | 33 ++++++++++++++++ .../Solution.ts | 5 +++ .../README.md | 35 ++++++++++++++++- .../README_EN.md | 39 +++++++++++++++++++ .../Solution.ts | 28 +++++++++++++ 16 files changed, 335 insertions(+), 10 deletions(-) create mode 100644 solution/1800-1899/1817.Finding the Users Active Minutes/Solution.ts create mode 100644 solution/1800-1899/1826.Faulty Sensor/Solution.ts create mode 100644 solution/1800-1899/1833.Maximum Ice Cream Bars/Solution.ts create mode 100644 solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/Solution.ts create mode 100644 solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/Solution.ts diff --git a/solution/1800-1899/1817.Finding the Users Active Minutes/README.md b/solution/1800-1899/1817.Finding the Users Active Minutes/README.md index 4359a48c758b6..6306710e13a07 100644 --- a/solution/1800-1899/1817.Finding the Users Active Minutes/README.md +++ b/solution/1800-1899/1817.Finding the Users Active Minutes/README.md @@ -60,7 +60,7 @@ ID=2 的用户执行操作的分钟分别是:2 和 3 。因此,该用户的 我们用哈希表 $d$ 记录每个用户的所有去重操作时间,然后遍历哈希表,统计每个用户的用户活跃分钟数,最后统计每个用户活跃分钟数的分布情况。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `logs` 的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $logs$ 的长度。 @@ -141,6 +141,25 @@ func findingUsersActiveMinutes(logs [][]int, k int) []int { } ``` +### **TypeScript** + +```ts +function findingUsersActiveMinutes(logs: number[][], k: number): number[] { + const d: Map> = new Map(); + for (const [i, t] of logs) { + if (!d.has(i)) { + d.set(i, new Set()); + } + d.get(i)!.add(t); + } + const ans: number[] = Array(k).fill(0); + for (const [_, ts] of d) { + ++ans[ts.size - 1]; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1817.Finding the Users Active Minutes/README_EN.md b/solution/1800-1899/1817.Finding the Users Active Minutes/README_EN.md index 04e7cb191a146..f62aa002751a1 100644 --- a/solution/1800-1899/1817.Finding the Users Active Minutes/README_EN.md +++ b/solution/1800-1899/1817.Finding the Users Active Minutes/README_EN.md @@ -50,6 +50,12 @@ Hence, answer[1] = 1, answer[2] = 1, and the remaining values are 0. ## Solutions +**Solution 1: Hash Table** + +We use a hash table $d$ to record all the unique operation times of each user, and then traverse the hash table to count the number of active minutes for each user. Finally, we count the distribution of the number of active minutes for each user. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the $logs$ array. + ### **Python3** @@ -125,6 +131,25 @@ func findingUsersActiveMinutes(logs [][]int, k int) []int { } ``` +### **TypeScript** + +```ts +function findingUsersActiveMinutes(logs: number[][], k: number): number[] { + const d: Map> = new Map(); + for (const [i, t] of logs) { + if (!d.has(i)) { + d.set(i, new Set()); + } + d.get(i)!.add(t); + } + const ans: number[] = Array(k).fill(0); + for (const [_, ts] of d) { + ++ans[ts.size - 1]; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1817.Finding the Users Active Minutes/Solution.ts b/solution/1800-1899/1817.Finding the Users Active Minutes/Solution.ts new file mode 100644 index 0000000000000..5a06c124ff555 --- /dev/null +++ b/solution/1800-1899/1817.Finding the Users Active Minutes/Solution.ts @@ -0,0 +1,14 @@ +function findingUsersActiveMinutes(logs: number[][], k: number): number[] { + const d: Map> = new Map(); + for (const [i, t] of logs) { + if (!d.has(i)) { + d.set(i, new Set()); + } + d.get(i)!.add(t); + } + const ans: number[] = Array(k).fill(0); + for (const [_, ts] of d) { + ++ans[ts.size - 1]; + } + return ans; +} diff --git a/solution/1800-1899/1819.Number of Different Subsequences GCDs/README.md b/solution/1800-1899/1819.Number of Different Subsequences GCDs/README.md index 317a62c71d317..416ad0232f85e 100644 --- a/solution/1800-1899/1819.Number of Different Subsequences GCDs/README.md +++ b/solution/1800-1899/1819.Number of Different Subsequences GCDs/README.md @@ -55,13 +55,13 @@ **方法一:枚举 + 数学** -对于数组 `nums` 的所有子序列,其最大公约数一定不超过数组中的最大值 $mx$。 +对于数组 $nums$ 的所有子序列,其最大公约数一定不超过数组中的最大值 $mx$。 -因此我们可以枚举 $[1,.. mx]$ 中的每个数 $x$,判断 $x$ 是否为数组 `nums` 的子序列的最大公约数,如果是,则答案加一。 +因此我们可以枚举 $[1,.. mx]$ 中的每个数 $x$,判断 $x$ 是否为数组 $nums$ 的子序列的最大公约数,如果是,则答案加一。 -那么问题转换为:判断 $x$ 是否为数组 `nums` 的子序列的最大公约数。我们可以通过枚举 $x$ 的倍数 $y$,判断 $y$ 是否在数组 `nums` 中,如果 $y$ 在数组 `nums` 中,则计算 $y$ 的最大公约数 $g$,如果出现 $g = x$,则 $x$ 是数组 `nums` 的子序列的最大公约数。 +那么问题转换为:判断 $x$ 是否为数组 $nums$ 的子序列的最大公约数。我们可以通过枚举 $x$ 的倍数 $y$,判断 $y$ 是否在数组 $nums$ 中,如果 $y$ 在数组 $nums$ 中,则计算 $y$ 的最大公约数 $g$,如果出现 $g = x$,则 $x$ 是数组 $nums$ 的子序列的最大公约数。 -时间复杂度 $O(n + M \times \log M)$,空间复杂度 $O(M)$。其中 $n$ 和 $M$ 分别是数组 `nums` 的长度和数组 `nums` 中的最大值。 +时间复杂度 $O(n + M \times \log M)$,空间复杂度 $O(M)$。其中 $n$ 和 $M$ 分别是数组 $nums$ 的长度和数组 $nums$ 中的最大值。 diff --git a/solution/1800-1899/1826.Faulty Sensor/README.md b/solution/1800-1899/1826.Faulty Sensor/README.md index 0c3218d00b6f7..ef48efe0cfbb4 100644 --- a/solution/1800-1899/1826.Faulty Sensor/README.md +++ b/solution/1800-1899/1826.Faulty Sensor/README.md @@ -152,6 +152,31 @@ func badSensor(sensor1 []int, sensor2 []int) int { } ``` +### **TypeScript** + +```ts +function badSensor(sensor1: number[], sensor2: number[]): number { + let i = 0; + const n = sensor1.length; + while (i < n - 1) { + if (sensor1[i] !== sensor2[i]) { + break; + } + ++i; + } + while (i < n - 1) { + if (sensor1[i + 1] !== sensor2[i]) { + return 1; + } + if (sensor1[i] !== sensor2[i + 1]) { + return 2; + } + ++i; + } + return -1; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1826.Faulty Sensor/README_EN.md b/solution/1800-1899/1826.Faulty Sensor/README_EN.md index 6abb2aad5885a..a03441335471a 100644 --- a/solution/1800-1899/1826.Faulty Sensor/README_EN.md +++ b/solution/1800-1899/1826.Faulty Sensor/README_EN.md @@ -133,6 +133,31 @@ func badSensor(sensor1 []int, sensor2 []int) int { } ``` +### **TypeScript** + +```ts +function badSensor(sensor1: number[], sensor2: number[]): number { + let i = 0; + const n = sensor1.length; + while (i < n - 1) { + if (sensor1[i] !== sensor2[i]) { + break; + } + ++i; + } + while (i < n - 1) { + if (sensor1[i + 1] !== sensor2[i]) { + return 1; + } + if (sensor1[i] !== sensor2[i + 1]) { + return 2; + } + ++i; + } + return -1; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1826.Faulty Sensor/Solution.ts b/solution/1800-1899/1826.Faulty Sensor/Solution.ts new file mode 100644 index 0000000000000..c246856ab4dbb --- /dev/null +++ b/solution/1800-1899/1826.Faulty Sensor/Solution.ts @@ -0,0 +1,20 @@ +function badSensor(sensor1: number[], sensor2: number[]): number { + let i = 0; + const n = sensor1.length; + while (i < n - 1) { + if (sensor1[i] !== sensor2[i]) { + break; + } + ++i; + } + while (i < n - 1) { + if (sensor1[i + 1] !== sensor2[i]) { + return 1; + } + if (sensor1[i] !== sensor2[i + 1]) { + return 2; + } + ++i; + } + return -1; +} diff --git a/solution/1800-1899/1833.Maximum Ice Cream Bars/README.md b/solution/1800-1899/1833.Maximum Ice Cream Bars/README.md index 8abc0607c6f1c..57caa1e517e5a 100644 --- a/solution/1800-1899/1833.Maximum Ice Cream Bars/README.md +++ b/solution/1800-1899/1833.Maximum Ice Cream Bars/README.md @@ -134,6 +134,22 @@ func maxIceCream(costs []int, coins int) int { } ``` +### **TypeScript** + +```ts +function maxIceCream(costs: number[], coins: number): number { + costs.sort((a, b) => a - b); + const n = costs.length; + for (let i = 0; i < n; ++i) { + if (coins < costs[i]) { + return i; + } + coins -= costs[i]; + } + return n; +} +``` + ### **JavaScript** ```js diff --git a/solution/1800-1899/1833.Maximum Ice Cream Bars/README_EN.md b/solution/1800-1899/1833.Maximum Ice Cream Bars/README_EN.md index af6b85f0f5767..897d8822d3d83 100644 --- a/solution/1800-1899/1833.Maximum Ice Cream Bars/README_EN.md +++ b/solution/1800-1899/1833.Maximum Ice Cream Bars/README_EN.md @@ -51,7 +51,13 @@ ## Solutions -Pay attention to the data range. The question can easily mislead us to use the 01 backpack (it will overtime). In fact, this question is a simple "greedy problem" (choose low-priced ice cream first) +**Solution 1: Greedy + Sorting** + +To buy as many ice creams as possible, and they can be purchased in any order, we should prioritize choosing ice creams with lower prices. + +Sort the $costs$ array, and then start buying from the ice cream with the lowest price, one by one, until it is no longer possible to buy, and return the number of ice creams that can be bought. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$, where $n$ is the length of the $costs$ array. @@ -118,6 +124,22 @@ func maxIceCream(costs []int, coins int) int { } ``` +### **TypeScript** + +```ts +function maxIceCream(costs: number[], coins: number): number { + costs.sort((a, b) => a - b); + const n = costs.length; + for (let i = 0; i < n; ++i) { + if (coins < costs[i]) { + return i; + } + coins -= costs[i]; + } + return n; +} +``` + ### **JavaScript** ```js diff --git a/solution/1800-1899/1833.Maximum Ice Cream Bars/Solution.ts b/solution/1800-1899/1833.Maximum Ice Cream Bars/Solution.ts new file mode 100644 index 0000000000000..4075591692622 --- /dev/null +++ b/solution/1800-1899/1833.Maximum Ice Cream Bars/Solution.ts @@ -0,0 +1,11 @@ +function maxIceCream(costs: number[], coins: number): number { + costs.sort((a, b) => a - b); + const n = costs.length; + for (let i = 0; i < n; ++i) { + if (coins < costs[i]) { + return i; + } + coins -= costs[i]; + } + return n; +} diff --git a/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README.md b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README.md index 3b195078760e5..26d7e82fbb08d 100644 --- a/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README.md +++ b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README.md @@ -49,7 +49,7 @@ **方法一:位运算** -假设数组 `arr1` 的元素分别为 $a_1, a_2, \cdots, a_n$,数组 `arr2` 的元素分别为 $b_1, b_2, \cdots, b_m$,那么题目答案为: +假设数组 $arr1$ 的元素分别为 $a_1, a_2, \cdots, a_n$,数组 $arr2$ 的元素分别为 $b_1, b_2, \cdots, b_m$,那么题目答案为: $$ \begin{aligned} @@ -66,9 +66,9 @@ $$ \text{ans} = (a_1 \oplus a_2 \oplus \cdots \oplus a_n) \wedge (b_1 \oplus b_2 \oplus \cdots \oplus b_m) $$ -即,数组 `arr1` 的异或和与数组 `arr2` 的异或和的与运算结果。 +即,数组 $arr1$ 的异或和与数组 $arr2$ 的异或和的与运算结果。 -时间复杂度 $O(n + m)$,空间复杂度 $O(1)$。其中 $n$ 和 $m$ 分别为数组 `arr1` 和 `arr2` 的长度。 +时间复杂度 $O(n + m)$,其中 $n$ 和 $m$ 分别为数组 $arr1$ 和 $arr2$ 的长度。空间复杂度 $O(1)$。 @@ -131,6 +131,16 @@ func getXORSum(arr1 []int, arr2 []int) int { } ``` +### **TypeScript** + +```ts +function getXORSum(arr1: number[], arr2: number[]): number { + const a = arr1.reduce((acc, x) => acc ^ x); + const b = arr2.reduce((acc, x) => acc ^ x); + return a & b; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README_EN.md b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README_EN.md index 06b8c6f0a9f82..aca506c9ef0d0 100644 --- a/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README_EN.md +++ b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/README_EN.md @@ -44,6 +44,29 @@ The XOR sum = 0 XOR 1 XOR 2 XOR 0 XOR 2 XOR 1 = 0. ## Solutions +**Solution 1: Bitwise Operation** + +Assume that the elements of array $arr1$ are $a_1, a_2, ..., a_n$, and the elements of array $arr2$ are $b_1, b_2, ..., b_m$. Then, the answer to the problem is: + +$$ +\begin{aligned} +\text{ans} &= (a_1 \wedge b_1) \oplus (a_1 \wedge b_2) ... (a_1 \wedge b_m) \\ +&\quad \oplus (a_2 \wedge b_1) \oplus (a_2 \wedge b_2) ... (a_2 \wedge b_m) \\ +&\quad \oplus \cdots \\ +&\quad \oplus (a_n \wedge b_1) \oplus (a_n \wedge b_2) ... (a_n \wedge b_m) \\ +\end{aligned} +$$ + +Since in Boolean algebra, the XOR operation is addition without carry, and the AND operation is multiplication, the above formula can be simplified as: + +$$ +\text{ans} = (a_1 \oplus a_2 \oplus \cdots \oplus a_n) \wedge (b_1 \oplus b_2 \oplus \cdots \oplus b_m) +$$ + +That is, the bitwise AND of the XOR sum of array $arr1$ and the XOR sum of array $arr2$. + +The time complexity is $O(n + m)$, where $n$ and $m$ are the lengths of arrays $arr1$ and $arr2$, respectively. The space complexity is $O(1)$. + ### **Python3** @@ -101,6 +124,16 @@ func getXORSum(arr1 []int, arr2 []int) int { } ``` +### **TypeScript** + +```ts +function getXORSum(arr1: number[], arr2: number[]): number { + const a = arr1.reduce((acc, x) => acc ^ x); + const b = arr2.reduce((acc, x) => acc ^ x); + return a & b; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/Solution.ts b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/Solution.ts new file mode 100644 index 0000000000000..8ebbda3c8c003 --- /dev/null +++ b/solution/1800-1899/1835.Find XOR Sum of All Pairs Bitwise AND/Solution.ts @@ -0,0 +1,5 @@ +function getXORSum(arr1: number[], arr2: number[]): number { + const a = arr1.reduce((acc, x) => acc ^ x); + const b = arr2.reduce((acc, x) => acc ^ x); + return a & b; +} diff --git a/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README.md b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README.md index bbc49ce7b675e..6ed3f9354b896 100644 --- a/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README.md +++ b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README.md @@ -48,7 +48,7 @@ **方法一:哈希表** -我们可以用哈希表 `cnt` 统计链表中每个元素出现的次数,然后遍历链表,删除出现次数大于 1 的元素。 +我们可以用哈希表 $cnt$ 统计链表中每个元素出现的次数,然后遍历链表,删除出现次数大于 1 的元素。 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为链表的长度。 @@ -176,6 +176,39 @@ func deleteDuplicatesUnsorted(head *ListNode) *ListNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function deleteDuplicatesUnsorted(head: ListNode | null): ListNode | null { + const cnt: Map = new Map(); + for (let cur = head; cur; cur = cur.next) { + const x = cur.val; + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const dummy = new ListNode(0, head); + for (let pre = dummy, cur = head; cur; cur = cur.next) { + if (cnt.get(cur.val)! > 1) { + pre.next = cur.next; + } else { + pre = cur; + } + } + return dummy.next; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README_EN.md b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README_EN.md index 5f68e9aefe791..3702a2ddc0948 100644 --- a/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README_EN.md +++ b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/README_EN.md @@ -43,6 +43,12 @@ ## Solutions +**Solution 1: Hash Table** + +We can use a hash table $cnt$ to count the number of occurrences of each element in the linked list, and then traverse the linked list to delete elements that appear more than once. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the linked list. + ### **Python3** @@ -163,6 +169,39 @@ func deleteDuplicatesUnsorted(head *ListNode) *ListNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function deleteDuplicatesUnsorted(head: ListNode | null): ListNode | null { + const cnt: Map = new Map(); + for (let cur = head; cur; cur = cur.next) { + const x = cur.val; + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const dummy = new ListNode(0, head); + for (let pre = dummy, cur = head; cur; cur = cur.next) { + if (cnt.get(cur.val)! > 1) { + pre.next = cur.next; + } else { + pre = cur; + } + } + return dummy.next; +} +``` + ### **...** ``` diff --git a/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/Solution.ts b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/Solution.ts new file mode 100644 index 0000000000000..662cbc6983f44 --- /dev/null +++ b/solution/1800-1899/1836.Remove Duplicates From an Unsorted Linked List/Solution.ts @@ -0,0 +1,28 @@ +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function deleteDuplicatesUnsorted(head: ListNode | null): ListNode | null { + const cnt: Map = new Map(); + for (let cur = head; cur; cur = cur.next) { + const x = cur.val; + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const dummy = new ListNode(0, head); + for (let pre = dummy, cur = head; cur; cur = cur.next) { + if (cnt.get(cur.val)! > 1) { + pre.next = cur.next; + } else { + pre = cur; + } + } + return dummy.next; +}