Skip to content

Commit 5ac1295

Browse files
authored
feat: add solutions to lc problem: No.1366 (doocs#3899)
No.1366.Rank Teams by Votes
1 parent 73793ca commit 5ac1295

File tree

12 files changed

+306
-148
lines changed

12 files changed

+306
-148
lines changed

solution/0100-0199/0160.Intersection of Two Linked Lists/README.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ tags:
110110

111111
### 方法一:双指针
112112

113-
我们使用两个指针 $a$, $b$ 分别指向两个链表 $headA$, $headB$。
113+
我们使用两个指针 $a$, $b$ 分别指向两个链表 $\textit{headA}$, $\textit{headB}$。
114114

115-
同时遍历链表,当 $a$ 到达链表 $headA$ 的末尾时,重新定位到链表 $headB$ 的头节点;当 $b$ 到达链表 $headB$ 的末尾时,重新定位到链表 $headA$ 的头节点。
115+
同时遍历链表,当 $a$ 到达链表 $\textit{headA}$ 的末尾时,重新定位到链表 $\textit{headB}$ 的头节点;当 $b$ 到达链表 $\textit{headB}$ 的末尾时,重新定位到链表 $\textit{headA}$ 的头节点。
116116

117117
若两指针相遇,所指向的结点就是第一个公共节点。若没相遇,说明两链表无公共节点,此时两个指针都指向 `null`,返回其中一个即可。
118118

119-
时间复杂度 $O(m+n)$,其中 $m$ 和 $n$ 分别是链表 $headA$ 和 $headB$ 的长度。空间复杂度 $O(1)$。
119+
时间复杂度 $O(m + n)$,其中 $m$ 和 $n$ 分别是链表 $\textit{headA}$ 和 $\textit{headB}$ 的长度。空间复杂度 $O(1)$。
120120

121121
<!-- tabs:start -->
122122

@@ -233,9 +233,8 @@ func getIntersectionNode(headA, headB *ListNode) *ListNode {
233233
*/
234234

235235
function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null {
236-
let a = headA;
237-
let b = headB;
238-
while (a != b) {
236+
let [a, b] = [headA, headB];
237+
while (a !== b) {
239238
a = a ? a.next : headB;
240239
b = b ? b.next : headA;
241240
}
@@ -260,9 +259,8 @@ function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): Li
260259
* @return {ListNode}
261260
*/
262261
var getIntersectionNode = function (headA, headB) {
263-
let a = headA;
264-
let b = headB;
265-
while (a != b) {
262+
let [a, b] = [headA, headB];
263+
while (a !== b) {
266264
a = a ? a.next : headB;
267265
b = b ? b.next : headA;
268266
}

solution/0100-0199/0160.Intersection of Two Linked Lists/README_EN.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ Explanation: The two lists do not intersect, so return null.
9494

9595
### Solution 1: Two Pointers
9696

97-
We use two pointers $a$ and $b$ to point to two linked lists $headA$ and $headB$ respectively.
97+
We use two pointers $a$ and $b$ to point to the heads of the two linked lists $\textit{headA}$ and $\textit{headB}$, respectively.
9898

99-
We traverse the linked lists simultaneously. When $a$ reaches the end of the linked list $headA$, it is repositioned to the head node of the linked list $headB$. When $b$ reaches the end of the linked list $headB$, it is repositioned to the head node of the linked list $headA$.
99+
Traverse the linked lists simultaneously. When $a$ reaches the end of $\textit{headA}$, redirect it to the head of $\textit{headB}$. Similarly, when $b$ reaches the end of $\textit{headB}$, redirect it to the head of $\textit{headA}$.
100100

101-
If the two pointers meet, the node they point to is the first common node. If they don't meet, it means that the two linked lists have no common nodes. At this time, both pointers point to `null`, and we can return either one.
101+
If the two pointers meet, the node they point to is the first common node. If they do not meet, it means the two linked lists have no common nodes, and both pointers will point to `null`. Return either pointer.
102102

103-
The time complexity is $O(m+n)$, where $m$ and $n$ are the lengths of the linked lists $headA$ and $headB$ respectively. The space complexity is $O(1)$.
103+
The time complexity is $O(m + n)$, where $m$ and $n$ are the lengths of the linked lists $\textit{headA}$ and $\textit{headB}$, respectively. The space complexity is $O(1)$.
104104

105105
<!-- tabs:start -->
106106

@@ -217,9 +217,8 @@ func getIntersectionNode(headA, headB *ListNode) *ListNode {
217217
*/
218218

219219
function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null {
220-
let a = headA;
221-
let b = headB;
222-
while (a != b) {
220+
let [a, b] = [headA, headB];
221+
while (a !== b) {
223222
a = a ? a.next : headB;
224223
b = b ? b.next : headA;
225224
}
@@ -244,9 +243,8 @@ function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): Li
244243
* @return {ListNode}
245244
*/
246245
var getIntersectionNode = function (headA, headB) {
247-
let a = headA;
248-
let b = headB;
249-
while (a != b) {
246+
let [a, b] = [headA, headB];
247+
while (a !== b) {
250248
a = a ? a.next : headB;
251249
b = b ? b.next : headA;
252250
}

solution/0100-0199/0160.Intersection of Two Linked Lists/Solution.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
* @return {ListNode}
1313
*/
1414
var getIntersectionNode = function (headA, headB) {
15-
let a = headA;
16-
let b = headB;
17-
while (a != b) {
15+
let [a, b] = [headA, headB];
16+
while (a !== b) {
1817
a = a ? a.next : headB;
1918
b = b ? b.next : headA;
2019
}

solution/0100-0199/0160.Intersection of Two Linked Lists/Solution.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
*/
1212

1313
function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null {
14-
let a = headA;
15-
let b = headB;
16-
while (a != b) {
14+
let [a, b] = [headA, headB];
15+
while (a !== b) {
1716
a = a ? a.next : headB;
1817
b = b ? b.next : headA;
1918
}

solution/1300-1399/1366.Rank Teams by Votes/README.md

Lines changed: 98 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ C 队获得三票「排位第二」,两票「排位第三」。
5555
<strong>输入:</strong>votes = ["WXYZ","XYZW"]
5656
<strong>输出:</strong>"XWYZ"
5757
<strong>解释:</strong>
58-
X 队在并列僵局打破后成为排名第一的团队。X 队和 W 队的「排位第一」票数一样,但是 X 队有一票「排位第二」,而 W 没有获得「排位第二」。
58+
X 队在并列僵局打破后成为排名第一的团队。X 队和 W 队的「排位第一」票数一样,但是 X 队有一票「排位第二」,而 W 没有获得「排位第二」。
5959
</pre>
6060

6161
<p><strong class="example">示例 3:</strong></p>
@@ -89,7 +89,7 @@ X 队在并列僵局打破后成为排名第一的团队。X 队和 W 队的「
8989

9090
对于每个候选人,我们可以统计他在每个排位上的票数,然后根据不同的排位依次比较票数,票数相同则比较字母。
9191

92-
时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n^2)$。其中 $n$ 为候选人的数量
92+
时间复杂度 $O(n \times m + m^2 \times \log m)$,空间复杂度 $O(m^2)$。其中 $n$ 是 $\textit{votes}$ 的长度,而 $m$ 是候选人的数量,即 $\textit{votes}[0]$ 的长度
9393

9494
<!-- tabs:start -->
9595

@@ -98,42 +98,41 @@ X 队在并列僵局打破后成为排名第一的团队。X 队和 W 队的「
9898
```python
9999
class Solution:
100100
def rankTeams(self, votes: List[str]) -> str:
101-
n = len(votes[0])
102-
cnt = defaultdict(lambda: [0] * n)
101+
m = len(votes[0])
102+
cnt = defaultdict(lambda: [0] * m)
103103
for vote in votes:
104104
for i, c in enumerate(vote):
105105
cnt[c][i] += 1
106-
return "".join(sorted(votes[0], key=lambda x: (cnt[x], -ord(x)), reverse=True))
106+
return "".join(sorted(cnt, key=lambda c: (cnt[c], -ord(c)), reverse=True))
107107
```
108108

109109
#### Java
110110

111111
```java
112112
class Solution {
113113
public String rankTeams(String[] votes) {
114-
int n = votes[0].length();
115-
int[][] cnt = new int[26][n];
114+
int m = votes[0].length();
115+
int[][] cnt = new int[26][m + 1];
116116
for (var vote : votes) {
117-
for (int i = 0; i < n; ++i) {
118-
cnt[vote.charAt(i) - 'A'][i]++;
117+
for (int i = 0; i < m; ++i) {
118+
++cnt[vote.charAt(i) - 'A'][i];
119119
}
120120
}
121-
Character[] cs = new Character[n];
122-
for (int i = 0; i < n; ++i) {
123-
cs[i] = votes[0].charAt(i);
121+
Character[] s = new Character[m];
122+
for (int i = 0; i < m; ++i) {
123+
s[i] = votes[0].charAt(i);
124124
}
125-
Arrays.sort(cs, (a, b) -> {
125+
Arrays.sort(s, (a, b) -> {
126126
int i = a - 'A', j = b - 'A';
127-
for (int k = 0; k < n; ++k) {
128-
int d = cnt[i][k] - cnt[j][k];
129-
if (d != 0) {
130-
return d > 0 ? -1 : 1;
127+
for (int k = 0; k < m; ++k) {
128+
if (cnt[i][k] != cnt[j][k]) {
129+
return cnt[j][k] - cnt[i][k];
131130
}
132131
}
133132
return a - b;
134133
});
135134
StringBuilder ans = new StringBuilder();
136-
for (char c : cs) {
135+
for (var c : s) {
137136
ans.append(c);
138137
}
139138
return ans.toString();
@@ -147,25 +146,25 @@ class Solution {
147146
class Solution {
148147
public:
149148
string rankTeams(vector<string>& votes) {
150-
int n = votes[0].size();
151-
int cnt[26][n];
152-
memset(cnt, 0, sizeof cnt);
153-
for (auto& vote : votes) {
154-
for (int i = 0; i < n; ++i) {
155-
cnt[vote[i] - 'A'][i]++;
149+
int m = votes[0].size();
150+
array<array<int, 27>, 26> cnt{};
151+
152+
for (const auto& vote : votes) {
153+
for (int i = 0; i < m; ++i) {
154+
++cnt[vote[i] - 'A'][i];
156155
}
157156
}
158-
string ans = votes[0];
159-
sort(ans.begin(), ans.end(), [&](auto& a, auto& b) {
157+
string s = votes[0];
158+
ranges::sort(s, [&](char a, char b) {
160159
int i = a - 'A', j = b - 'A';
161-
for (int k = 0; k < n; ++k) {
160+
for (int k = 0; k < m; ++k) {
162161
if (cnt[i][k] != cnt[j][k]) {
163162
return cnt[i][k] > cnt[j][k];
164163
}
165164
}
166165
return a < b;
167166
});
168-
return ans;
167+
return string(s.begin(), s.end());
169168
}
170169
};
171170
```
@@ -174,24 +173,83 @@ public:
174173
175174
```go
176175
func rankTeams(votes []string) string {
177-
cnt := [26][26]int{}
176+
m := len(votes[0])
177+
cnt := [26][27]int{}
178178
for _, vote := range votes {
179-
for i, c := range vote {
180-
cnt[c-'A'][i]++
179+
for i, ch := range vote {
180+
cnt[ch-'A'][i]++
181181
}
182182
}
183-
ans := []byte(votes[0])
184-
sort.Slice(ans, func(i, j int) bool {
185-
cnt1, cnt2 := cnt[ans[i]-'A'], cnt[ans[j]-'A']
186-
for k, a := range cnt1 {
187-
b := cnt2[k]
188-
if a != b {
189-
return a > b
183+
s := []rune(votes[0])
184+
sort.Slice(s, func(i, j int) bool {
185+
a, b := s[i]-'A', s[j]-'A'
186+
for k := 0; k < m; k++ {
187+
if cnt[a][k] != cnt[b][k] {
188+
return cnt[a][k] > cnt[b][k]
190189
}
191190
}
192-
return ans[i] < ans[j]
191+
return s[i] < s[j]
193192
})
194-
return string(ans)
193+
return string(s)
194+
}
195+
```
196+
197+
#### TypeScript
198+
199+
```ts
200+
function rankTeams(votes: string[]): string {
201+
const m = votes[0].length;
202+
const cnt: number[][] = Array.from({ length: 26 }, () => Array(m + 1).fill(0));
203+
for (const vote of votes) {
204+
for (let i = 0; i < m; i++) {
205+
cnt[vote.charCodeAt(i) - 65][i]++;
206+
}
207+
}
208+
const s: string[] = votes[0].split('');
209+
s.sort((a, b) => {
210+
const i = a.charCodeAt(0) - 65;
211+
const j = b.charCodeAt(0) - 65;
212+
for (let k = 0; k < m; k++) {
213+
if (cnt[i][k] !== cnt[j][k]) {
214+
return cnt[j][k] - cnt[i][k];
215+
}
216+
}
217+
return a.localeCompare(b);
218+
});
219+
return s.join('');
220+
}
221+
```
222+
223+
#### Rust
224+
225+
```rust
226+
impl Solution {
227+
pub fn rank_teams(votes: Vec<String>) -> String {
228+
let m = votes[0].len();
229+
let mut cnt = vec![vec![0; m + 1]; 26];
230+
231+
for vote in &votes {
232+
for (i, ch) in vote.chars().enumerate() {
233+
cnt[(ch as u8 - b'A') as usize][i] += 1;
234+
}
235+
}
236+
237+
let mut s: Vec<char> = votes[0].chars().collect();
238+
239+
s.sort_by(|&a, &b| {
240+
let i = (a as u8 - b'A') as usize;
241+
let j = (b as u8 - b'A') as usize;
242+
243+
for k in 0..m {
244+
if cnt[i][k] != cnt[j][k] {
245+
return cnt[j][k].cmp(&cnt[i][k]);
246+
}
247+
}
248+
a.cmp(&b)
249+
});
250+
251+
s.into_iter().collect()
252+
}
195253
}
196254
```
197255

0 commit comments

Comments
 (0)