Skip to content

Commit 0b5df44

Browse files
committed
feat: add solutions to lc problem: No.2131
No.2131.Longest Palindrome by Concatenating Two Letter Words
1 parent 6085f2f commit 0b5df44

File tree

5 files changed

+114
-50
lines changed

5 files changed

+114
-50
lines changed
Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,41 @@
1-
#include <stdlib.h>
21

3-
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
4-
int capacity = 1;
5-
while (capacity < numsSize * 2) capacity <<= 1;
6-
int* keys = malloc(capacity * sizeof(int));
7-
int* vals = malloc(capacity * sizeof(int));
8-
char* used = calloc(capacity, sizeof(char));
9-
if (!keys || !vals || !used) {
10-
free(keys);
11-
free(vals);
12-
free(used);
13-
*returnSize = 0;
14-
return NULL;
15-
}
16-
for (int i = 0; i < numsSize; ++i) {
17-
int x = nums[i];
18-
int y = target - x;
19-
unsigned int h = (unsigned int) y & (capacity - 1);
20-
while (used[h]) {
21-
if (keys[h] == y) {
22-
int* res = malloc(2 * sizeof(int));
23-
res[0] = vals[h];
24-
res[1] = i;
25-
*returnSize = 2;
26-
free(keys);
27-
free(vals);
28-
free(used);
29-
return res;
30-
}
31-
h = (h + 1) & (capacity - 1);
2+
/**
3+
* Definition for singly-linked list.
4+
* struct ListNode {
5+
* int val;
6+
* struct ListNode *next;
7+
* };
8+
*/
9+
10+
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
11+
struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
12+
dummy->val = 0;
13+
dummy->next = NULL;
14+
struct ListNode* curr = dummy;
15+
int carry = 0;
16+
17+
while (l1 != NULL || l2 != NULL || carry != 0) {
18+
int sum = carry;
19+
if (l1 != NULL) {
20+
sum += l1->val;
21+
l1 = l1->next;
22+
}
23+
if (l2 != NULL) {
24+
sum += l2->val;
25+
l2 = l2->next;
3226
}
33-
unsigned int h2 = (unsigned int) x & (capacity - 1);
34-
while (used[h2]) h2 = (h2 + 1) & (capacity - 1);
35-
used[h2] = 1;
36-
keys[h2] = x;
37-
vals[h2] = i;
27+
28+
carry = sum / 10;
29+
int val = sum % 10;
30+
31+
struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
32+
newNode->val = val;
33+
newNode->next = NULL;
34+
curr->next = newNode;
35+
curr = curr->next;
3836
}
39-
*returnSize = 0;
40-
free(keys);
41-
free(vals);
42-
free(used);
43-
return NULL;
44-
}
37+
38+
struct ListNode* result = dummy->next;
39+
free(dummy);
40+
return result;
41+
}

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,17 @@ tags:
7373

7474
### 方法一:贪心 + 哈希表
7575

76-
我们先用哈希表 `cnt` 统计每个单词出现的次数。
76+
我们先用一个哈希表 $\textit{cnt}$ 统计每个单词出现的次数。
7777

78-
遍历 `cnt` 中的每个单词 $k$ 以及其出现次数 $v$:
78+
遍历 $\textit{cnt}$ 中的每个单词 $k$ 以及其出现次数 $v$:
7979

80-
如果 $k$ 中两个字母相同,那么我们可以将 $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ 个 $k$ 连接到回文串的前后,此时如果 $k$ 还剩余一个,那么我们可以先记录到 $x$ 中。
80+
- 如果 $k$ 中两个字母相同,那么我们可以将 $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ 个 $k$ 连接到回文串的前后,此时如果 $k$ 还剩余一个,那么我们可以先记录到 $x$ 中。
8181

82-
如果 $k$ 中两个字母不同,那么我们要找到一个单词 $k'$,使得 $k'$ 中的两个字母与 $k$ 相反,即 $k' = k[1] + k[0]$。如果 $k'$ 存在,那么我们可以将 $\min(v, cnt[k'])$ 个 $k$ 连接到回文串的前后。
82+
- 如果 $k$ 中两个字母不同,那么我们要找到一个单词 $k'$,使得 $k'$ 中的两个字母与 $k$ 相反,即 $k' = k[1] + k[0]$。如果 $k'$ 存在,那么我们可以将 $\min(v, \textit{cnt}[k'])$ 个 $k$ 连接到回文串的前后。
8383

8484
遍历结束后,如果 $x$ 不为空,那么我们还可以将一个单词连接到回文串的中间。
8585

86-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ `words` 的长度
86+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为单词的数量
8787

8888
<!-- tabs:start -->
8989

@@ -111,7 +111,7 @@ class Solution {
111111
public int longestPalindrome(String[] words) {
112112
Map<String, Integer> cnt = new HashMap<>();
113113
for (var w : words) {
114-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
114+
cnt.merge(w, 1, Integer::sum);
115115
}
116116
int ans = 0, x = 0;
117117
for (var e : cnt.entrySet()) {
@@ -183,6 +183,26 @@ func longestPalindrome(words []string) int {
183183
}
184184
```
185185

186+
#### TypeScript
187+
188+
```ts
189+
function longestPalindrome(words: string[]): number {
190+
const cnt = new Map<string, number>();
191+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
192+
let [ans, x] = [0, 0];
193+
for (const [k, v] of cnt.entries()) {
194+
if (k[0] === k[1]) {
195+
x += v & 1;
196+
ans += Math.floor(v / 2) * 2 * 2;
197+
} else {
198+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
199+
}
200+
}
201+
ans += x ? 2 : 0;
202+
return ans;
203+
}
204+
```
205+
186206
<!-- tabs:end -->
187207

188208
<!-- solution:end -->

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/README_EN.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,19 @@ Note that &quot;ll&quot; is another longest palindrome that can be created, and
7373

7474
<!-- solution:start -->
7575

76-
### Solution 1
76+
### Solution 1: Greedy + Hash Table
77+
78+
First, we use a hash table $\textit{cnt}$ to count the occurrences of each word.
79+
80+
Iterate through each word $k$ and its count $v$ in $\textit{cnt}$:
81+
82+
- If the two letters in $k$ are the same, we can concatenate $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ copies of $k$ to the front and back of the palindrome. If there is one $k$ left, we can record it in $x$ for now.
83+
84+
- If the two letters in $k$ are different, we need to find a word $k'$ such that the two letters in $k'$ are the reverse of $k$, i.e., $k' = k[1] + k[0]$. If $k'$ exists, we can concatenate $\min(v, \textit{cnt}[k'])$ copies of $k$ to the front and back of the palindrome.
85+
86+
After the iteration, if $x$ is not empty, we can also place one word in the middle of the palindrome.
87+
88+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of words.
7789

7890
<!-- tabs:start -->
7991

@@ -101,7 +113,7 @@ class Solution {
101113
public int longestPalindrome(String[] words) {
102114
Map<String, Integer> cnt = new HashMap<>();
103115
for (var w : words) {
104-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
116+
cnt.merge(w, 1, Integer::sum);
105117
}
106118
int ans = 0, x = 0;
107119
for (var e : cnt.entrySet()) {
@@ -173,6 +185,26 @@ func longestPalindrome(words []string) int {
173185
}
174186
```
175187

188+
#### TypeScript
189+
190+
```ts
191+
function longestPalindrome(words: string[]): number {
192+
const cnt = new Map<string, number>();
193+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
194+
let [ans, x] = [0, 0];
195+
for (const [k, v] of cnt.entries()) {
196+
if (k[0] === k[1]) {
197+
x += v & 1;
198+
ans += Math.floor(v / 2) * 2 * 2;
199+
} else {
200+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
201+
}
202+
}
203+
ans += x ? 2 : 0;
204+
return ans;
205+
}
206+
```
207+
176208
<!-- tabs:end -->
177209

178210
<!-- solution:end -->

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/Solution.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Solution {
22
public int longestPalindrome(String[] words) {
33
Map<String, Integer> cnt = new HashMap<>();
44
for (var w : words) {
5-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
5+
cnt.merge(w, 1, Integer::sum);
66
}
77
int ans = 0, x = 0;
88
for (var e : cnt.entrySet()) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function longestPalindrome(words: string[]): number {
2+
const cnt = new Map<string, number>();
3+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
4+
let [ans, x] = [0, 0];
5+
for (const [k, v] of cnt.entries()) {
6+
if (k[0] === k[1]) {
7+
x += v & 1;
8+
ans += Math.floor(v / 2) * 2 * 2;
9+
} else {
10+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
11+
}
12+
}
13+
ans += x ? 2 : 0;
14+
return ans;
15+
}

0 commit comments

Comments
 (0)