Skip to content

feat: update solutions to lc problems: No.2262,2264 #1719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions solution/2200-2299/2262.Total Appeal of A String/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,20 @@

<!-- 这里可写通用的实现逻辑 -->

遍历字符串 s 每个字符 `s[i]`, 维护以 `s[i]` 结尾的子串的引力值之和 t,遍历过程中累加 t 得到结果。
**方法一:枚举**

若当前遍历到字符 `s[i]`,对应的引力值 t 的计算逻辑为:
我们可以枚举以每个字符 $s[i]$ 结尾的字符串,计算其引力值之和 $t$,最后将所有 $t$ 相加即可。

1. 如果 `s[i]` 在之前没出现过,那么以 `s[i-1]` 结尾的每个子串的引力值都会加上 1,引力值之和会增加 i,再加上 1(`s[i]` 单独组成的子串的引力值),得到 `s[i]` 的引力值 t。
1. 如果 `s[i]` 在之前出现过,定义最近一次出现的下标为 j,那么向子串 `s[0..i-1], s[1..i-1], ..., s[j..i-1]` 的末尾添加 `s[i]`,引力值不变。而 `s[j+1..i-1], s[j+2..i=1], ..., s[i-1..i-1]` 由于不包含 s[i],这些子串的引力值增加 1,因此有 i-j-1 个子串的引力值会增加 1,引力值之和增加 i-j-1,再加上 1,得到 `s[i]` 的引力值 t。
考虑遍历到 $s[i]$ 时,即把 $s[i]$ 添加到以 $s[i-1]$ 结尾的子字符串的后面,其引力值之和 $t$ 的变化情况:

此过程中,我们用 pos 记录每个字符最近一次出现的位置。
1. 如果 $s[i]$ 在之前没出现过,那么所有以 $s[i-1]$ 结尾的子字符串的引力值都会增加 $1$,共有 $i$ 个,所以 $t$ 增加 $i$,再加上 $s[i]$ 自身的引力值 $1$,所以 $t$ 一共增加 $i+1$;
1. 如果 $s[i]$ 在之前出现过,不妨记上次出现的的位置为 $j$,那么我们向子字符串 $s[0..i-1]$, $[1..i-1]$, $s[2..i-1]$, $\cdots$, $s[j..i-1]$ 后面添加 $s[i]$,这些子字符串的引力值不会发生变化,因为 $s[i]$ 已经在这些子字符串中出现过了;而子字符串 $s[j+1..i-1]$, $s[j+2..i-1]$, $\cdots$, $s[i-1]$ 的引力值都会增加 $1$,共有 $i-j-1$ 个,所以 $t$ 增加 $i-j-1$,再加上 $s[i]$ 自身的引力值 $1$,所以 $t$ 一共增加 $i-j$。

综上,我们可以用一个数组 $pos$ 记录每个字符上次出现的位置,初始时所有位置都为 $-1$,

接下来,我们遍历字符串,每一次我们更新以当前字符结尾的子字符串的引力值之和 $t = t + i - pos[c]$,其中 $c$ 是当前字符,累加 $t$ 到答案中。然后我们更新 $pos[c]$ 为当前位置 $i$。继续遍历直到字符串结束。

时间复杂度 $O(n)$,空间复杂度 $O(|\Sigma|)$,其中 $n$ 是字符串 $s$ 的长度;而 $|\Sigma|$ 是字符集的大小,本题中 $|\Sigma| = 26$。

<!-- tabs:start -->

Expand Down Expand Up @@ -148,15 +154,17 @@ func appealSum(s string) int64 {

```ts
function appealSum(s: string): number {
const pos: number[] = Array(26).fill(-1);
const n = s.length;
let dp = new Array(n + 1).fill(0);
const hashMap = new Map();
for (let i = 0; i < n; i++) {
const c = s.charAt(i);
dp[i + 1] = dp[i] + i + 1 - (hashMap.get(c) || 0);
hashMap.set(c, i + 1);
let ans = 0;
let t = 0;
for (let i = 0; i < n; ++i) {
const c = s.charCodeAt(i) - 97;
t += i - pos[c];
ans += t;
pos[c] = i;
}
return dp.reduce((a, c) => a + c, 0);
return ans;
}
```

Expand Down
31 changes: 24 additions & 7 deletions solution/2200-2299/2262.Total Appeal of A String/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ The total sum is 4 + 6 + 6 + 4 = 20.

## Solutions

**Solution 1: Enumeration**

We can enumerate all the substrings that end with each character $s[i]$ and calculate their gravitational value sum $t$. Finally, we add up all the $t$ to get the total gravitational value sum.

When we reach $s[i]$, which is added to the end of the substring that ends with $s[i-1]$, we consider the change of the gravitational value sum $t$:

If $s[i]$ has not appeared before, then the gravitational value of all substrings that end with $s[i-1]$ will increase by $1$, and there are a total of $i$ such substrings. Therefore, $t$ increases by $i$, plus the gravitational value of $s[i]$ itself, which is $1$. Therefore, $t$ increases by a total of $i+1$.

If $s[i]$ has appeared before, let the last appearance position be $j$. Then we add $s[i]$ to the end of the substrings $s[0..i-1]$, $[1..i-1]$, $s[2..i-1]$, $\cdots$, $s[j..i-1]$. The gravitational value of these substrings will not change because $s[i]$ has already appeared in these substrings. The gravitational value of the substrings $s[j+1..i-1]$, $s[j+2..i-1]$, $\cdots$, $s[i-1]$ will increase by $1$, and there are a total of $i-j-1$ such substrings. Therefore, $t$ increases by $i-j-1$, plus the gravitational value of $s[i]$ itself, which is $1$. Therefore, $t$ increases by a total of $i-j$.
Therefore, we can use an array $pos$ to record the last appearance position of each character. Initially, all positions are set to $-1$.

Next, we traverse the string, and each time we update the gravitational value sum $t$ of the substring that ends with the current character to $t = t + i - pos[c]$, where $c$ is the current character. We add $t$ to the answer. Then we update $pos[c]$ to the current position $i$. We continue to traverse until the end of the string.

The time complexity is $O(n)$, and the space complexity is $O(|\Sigma|)$, where $n$ is the length of the string $s$, and $|\Sigma|$ is the size of the character set. In this problem, $|\Sigma| = 26$.

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -131,15 +146,17 @@ func appealSum(s string) int64 {

```ts
function appealSum(s: string): number {
const pos: number[] = Array(26).fill(-1);
const n = s.length;
let dp = new Array(n + 1).fill(0);
const hashMap = new Map();
for (let i = 0; i < n; i++) {
const c = s.charAt(i);
dp[i + 1] = dp[i] + i + 1 - (hashMap.get(c) || 0);
hashMap.set(c, i + 1);
let ans = 0;
let t = 0;
for (let i = 0; i < n; ++i) {
const c = s.charCodeAt(i) - 97;
t += i - pos[c];
ans += t;
pos[c] = i;
}
return dp.reduce((a, c) => a + c, 0);
return ans;
}
```

Expand Down
16 changes: 9 additions & 7 deletions solution/2200-2299/2262.Total Appeal of A String/Solution.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
function appealSum(s: string): number {
const pos: number[] = Array(26).fill(-1);
const n = s.length;
let dp = new Array(n + 1).fill(0);
const hashMap = new Map();
for (let i = 0; i < n; i++) {
const c = s.charAt(i);
dp[i + 1] = dp[i] + i + 1 - (hashMap.get(c) || 0);
hashMap.set(c, i + 1);
let ans = 0;
let t = 0;
for (let i = 0; i < n; ++i) {
const c = s.charCodeAt(i) - 97;
t += i - pos[c];
ans += t;
pos[c] = i;
}
return dp.reduce((a, c) => a + c, 0);
return ans;
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@

<!-- 这里可写通用的实现逻辑 -->

**方法一:枚举**

我们可以从大到小枚举每个数字 $i$,其中 $0 \le i \le 9$,然后判断连续的三个 $i$ 构成的字符串 $s$ 是否是 $num$ 的子串,若是,直接返回 $s$ 即可。

若枚举完所有的 $i$ 都没有找到满足条件的字符串,则返回空字符串。

时间复杂度 $O(10 \times n)$,其中 $n$ 是字符串 $num$ 的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

### **Python3**
Expand All @@ -72,10 +80,9 @@
class Solution:
def largestGoodInteger(self, num: str) -> str:
for i in range(9, -1, -1):
t = str(i) * 3
if t in num:
return t
return ''
if (s := str(i) * 3) in num:
return s
return ""
```

### **Java**
Expand All @@ -86,37 +93,27 @@ class Solution:
class Solution {
public String largestGoodInteger(String num) {
for (int i = 9; i >= 0; i--) {
String ret = String.valueOf(i).repeat(3);
if (num.contains(ret)) {
return ret;
String s = String.valueOf(i).repeat(3);
if (num.contains(s)) {
return s;
}
}
return "";
}
}
```

### **TypeScript**

```ts
function largestGoodInteger(num: string): string {
for (let i = 9; i >= 0; i--) {
const c = String(i).repeat(3);
if (num.includes(c)) return c;
}
return '';
}
```

### **C++**

```cpp
class Solution {
public:
string largestGoodInteger(string num) {
for (char i = '9'; i >= '0'; --i) {
string t(3, i);
if (num.find(t) != string::npos) return t;
string s(3, i);
if (num.find(s) != string::npos) {
return s;
}
}
return "";
}
Expand All @@ -128,15 +125,28 @@ public:
```go
func largestGoodInteger(num string) string {
for c := '9'; c >= '0'; c-- {
t := strings.Repeat(string(c), 3)
if strings.Contains(num, t) {
return t
if s := strings.Repeat(string(c), 3); strings.Contains(num, s) {
return s
}
}
return ""
}
```

### **TypeScript**

```ts
function largestGoodInteger(num: string): string {
for (let i = 9; i >= 0; i--) {
const s = String(i).repeat(3);
if (num.includes(s)) {
return s;
}
}
return '';
}
```

### **...**

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@

## Solutions

**Solution 1: Enumeration**

We can enumerate each digit $i$ from large to small, where $0 \le i \le 9$, and then check whether the string $s$ consisting of three consecutive $i$ is a substring of $num$. If it is, we directly return $s$.

If we have enumerated all the possible values of $i$ and still haven't found a substring that satisfies the condition, we return an empty string.

The time complexity is $O(10 \times n)$, where $n$ is the length of the string $num$. The space complexity is $O(1)$.

<!-- tabs:start -->

### **Python3**
Expand All @@ -64,10 +72,9 @@
class Solution:
def largestGoodInteger(self, num: str) -> str:
for i in range(9, -1, -1):
t = str(i) * 3
if t in num:
return t
return ''
if (s := str(i) * 3) in num:
return s
return ""
```

### **Java**
Expand All @@ -76,37 +83,27 @@ class Solution:
class Solution {
public String largestGoodInteger(String num) {
for (int i = 9; i >= 0; i--) {
String ret = String.valueOf(i).repeat(3);
if (num.contains(ret)) {
return ret;
String s = String.valueOf(i).repeat(3);
if (num.contains(s)) {
return s;
}
}
return "";
}
}
```

### **TypeScript**

```ts
function largestGoodInteger(num: string): string {
for (let i = 9; i >= 0; i--) {
const c = String(i).repeat(3);
if (num.includes(c)) return c;
}
return '';
}
```

### **C++**

```cpp
class Solution {
public:
string largestGoodInteger(string num) {
for (char i = '9'; i >= '0'; --i) {
string t(3, i);
if (num.find(t) != string::npos) return t;
string s(3, i);
if (num.find(s) != string::npos) {
return s;
}
}
return "";
}
Expand All @@ -118,15 +115,28 @@ public:
```go
func largestGoodInteger(num string) string {
for c := '9'; c >= '0'; c-- {
t := strings.Repeat(string(c), 3)
if strings.Contains(num, t) {
return t
if s := strings.Repeat(string(c), 3); strings.Contains(num, s) {
return s
}
}
return ""
}
```

### **TypeScript**

```ts
function largestGoodInteger(num: string): string {
for (let i = 9; i >= 0; i--) {
const s = String(i).repeat(3);
if (num.includes(s)) {
return s;
}
}
return '';
}
```

### **...**

```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
class Solution {
public:
string largestGoodInteger(string num) {
for (char i = '9'; i >= '0'; --i) {
string t(3, i);
if (num.find(t) != string::npos) return t;
}
return "";
}
class Solution {
public:
string largestGoodInteger(string num) {
for (char i = '9'; i >= '0'; --i) {
string s(3, i);
if (num.find(s) != string::npos) {
return s;
}
}
return "";
}
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
func largestGoodInteger(num string) string {
for c := '9'; c >= '0'; c-- {
t := strings.Repeat(string(c), 3)
if strings.Contains(num, t) {
return t
if s := strings.Repeat(string(c), 3); strings.Contains(num, s) {
return s
}
}
return ""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class Solution {
public String largestGoodInteger(String num) {
for (int i = 9; i >= 0; i--) {
String ret = String.valueOf(i).repeat(3);
if (num.contains(ret)) {
return ret;
}
}
return "";
}
}
class Solution {
public String largestGoodInteger(String num) {
for (int i = 9; i >= 0; i--) {
String s = String.valueOf(i).repeat(3);
if (num.contains(s)) {
return s;
}
}
return "";
}
}
Loading