Skip to content

[pull] main from doocs:main #507

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
Apr 2, 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
2 changes: 1 addition & 1 deletion solution/0700-0799/0789.Escape The Ghosts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<p>如果你可以在任何阻碍者抓住你 <strong>之前</strong> 到达目的地(阻碍者可以采取任意行动方式),则被视为逃脱成功。如果你和阻碍者 <strong>同时</strong> 到达了一个位置(包括目的地)&nbsp;<strong>都不算</strong>&nbsp;是逃脱成功。</p>

<p>只有在你有可能成功逃脱时,输出 <code>true</code> ;否则,输出 <code>false</code> 。</p>
<p>如果不管阻碍者怎么移动都可以成功逃脱时,输出 <code>true</code> ;否则,输出 <code>false</code> 。</p>
&nbsp;

<p><strong>示例 1:</strong></p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ $$

时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为多边形的顶点数。

相似题目:

- [1312. 让字符串成为回文串的最少插入次数](/solution/1300-1399/1312.Minimum%20Insertion%20Steps%20to%20Make%20a%20String%20Palindrome/README.md)

<!-- tabs:start -->

### **Python3**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,23 @@

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

**方法一:动态规划(区间 DP)**
**方法一:记忆化搜索**

我们设计一个函数 $dfs(i, j)$,表示将字符串 $s[i..j]$ 变成回文串所需要的最少操作次数。那么答案就是 $dfs(0, n - 1)$。

函数 $dfs(i, j)$ 的计算过程如下:

如果 $i \geq j$,此时无需插入任何字符,我们直接返回 $0$。

否则,我们判断 $s[i]$ 与 $s[j]$ 是否相等,如果 $s[i]=s[j]$,那么我们只需要将 $s[i+1..j-1]$ 变成回文串,那么我们返回 $dfs(i + 1, j - 1)$。否则,我们可以在 $s[i]$ 的左侧或者 $s[j]$ 的右侧插入一个与另一侧相同的字符,那么 $dfs(i, j) = \min(dfs(i + 1, j), dfs(i, j - 1)) + 1$。

为了避免重复计算,我们可以使用记忆化搜索,即使用哈希表或者数组来存储已经计算过的函数值。

最后,我们返回 $dfs(0, n - 1)$ 即可。

时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。

**方法二:动态规划(区间 DP)**

我们定义 $f[i][j]$ 表示将字符串 $s[i..j]$ 变成回文串所需要的最少操作次数。初始时 $f[i][j]=0$,答案即为 $f[0][n-1]$。

Expand All @@ -70,12 +86,30 @@ $$

时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。

相似题目:

- [1039. 多边形三角剖分的最低得分](/solution/1000-1099/1039.Minimum%20Score%20Triangulation%20of%20Polygon/README.md)

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python
class Solution:
def minInsertions(self, s: str) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= j:
return 0
if s[i] == s[j]:
return dfs(i + 1, j - 1)
return 1 + min(dfs(i + 1, j), dfs(i, j - 1))

return dfs(0, len(s) - 1)
```

```python
class Solution:
def minInsertions(self, s: str) -> int:
Expand Down Expand Up @@ -109,6 +143,36 @@ class Solution:

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
private Integer[][] f;
private String s;

public int minInsertions(String s) {
this.s = s;
int n = s.length();
f = new Integer[n][n];
return dfs(0, n - 1);
}

private int dfs(int i, int j) {
if (i >= j) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
int ans = 1 << 30;
if (s.charAt(i) == s.charAt(j)) {
ans = dfs(i + 1, j - 1);
} else {
ans = Math.min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
}
return f[i][j] = ans;
}
}
```

```java
class Solution {
public int minInsertions(String s) {
Expand Down Expand Up @@ -150,6 +214,33 @@ class Solution {

### **C++**

```cpp
class Solution {
public:
int minInsertions(string s) {
int n = s.size();
int f[n][n];
memset(f, -1, sizeof(f));
function<int(int, int)> dfs = [&](int i, int j) -> int {
if (i >= j) {
return 0;
}
if (f[i][j] != -1) {
return f[i][j];
}
int ans = 1 << 30;
if (s[i] == s[j]) {
ans = dfs(i + 1, j - 1);
} else {
ans = min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
}
return f[i][j] = ans;
};
return dfs(0, n - 1);
}
};
```

```cpp
class Solution {
public:
Expand Down Expand Up @@ -195,6 +286,44 @@ public:

### **Go**

```go
func minInsertions(s string) int {
n := len(s)
f := make([][]int, n)
for i := range f {
f[i] = make([]int, n)
for j := range f[i] {
f[i][j] = -1
}
}
var dfs func(i, j int) int
dfs = func(i, j int) int {
if i >= j {
return 0
}
if f[i][j] != -1 {
return f[i][j]
}
ans := 1 << 30
if s[i] == s[j] {
ans = dfs(i+1, j-1)
} else {
ans = min(dfs(i+1, j), dfs(i, j-1)) + 1
}
f[i][j] = ans
return ans
}
return dfs(0, n-1)
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
```

```go
func minInsertions(s string) int {
n := len(s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@

### **Python3**

```python
class Solution:
def minInsertions(self, s: str) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= j:
return 0
if s[i] == s[j]:
return dfs(i + 1, j - 1)
return 1 + min(dfs(i + 1, j), dfs(i, j - 1))

return dfs(0, len(s) - 1)
```

```python
class Solution:
def minInsertions(self, s: str) -> int:
Expand Down Expand Up @@ -80,6 +94,36 @@ class Solution:

### **Java**

```java
class Solution {
private Integer[][] f;
private String s;

public int minInsertions(String s) {
this.s = s;
int n = s.length();
f = new Integer[n][n];
return dfs(0, n - 1);
}

private int dfs(int i, int j) {
if (i >= j) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
int ans = 1 << 30;
if (s.charAt(i) == s.charAt(j)) {
ans = dfs(i + 1, j - 1);
} else {
ans = Math.min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
}
return f[i][j] = ans;
}
}
```

```java
class Solution {
public int minInsertions(String s) {
Expand Down Expand Up @@ -121,6 +165,33 @@ class Solution {

### **C++**

```cpp
class Solution {
public:
int minInsertions(string s) {
int n = s.size();
int f[n][n];
memset(f, -1, sizeof(f));
function<int(int, int)> dfs = [&](int i, int j) -> int {
if (i >= j) {
return 0;
}
if (f[i][j] != -1) {
return f[i][j];
}
int ans = 1 << 30;
if (s[i] == s[j]) {
ans = dfs(i + 1, j - 1);
} else {
ans = min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
}
return f[i][j] = ans;
};
return dfs(0, n - 1);
}
};
```

```cpp
class Solution {
public:
Expand Down Expand Up @@ -166,6 +237,44 @@ public:

### **Go**

```go
func minInsertions(s string) int {
n := len(s)
f := make([][]int, n)
for i := range f {
f[i] = make([]int, n)
for j := range f[i] {
f[i][j] = -1
}
}
var dfs func(i, j int) int
dfs = func(i, j int) int {
if i >= j {
return 0
}
if f[i][j] != -1 {
return f[i][j]
}
ans := 1 << 30
if s[i] == s[j] {
ans = dfs(i+1, j-1)
} else {
ans = min(dfs(i+1, j), dfs(i, j-1)) + 1
}
f[i][j] = ans
return ans
}
return dfs(0, n-1)
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
```

```go
func minInsertions(s string) int {
n := len(s)
Expand Down
Loading