Skip to content
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
1 change: 1 addition & 0 deletions Index/模拟.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
| [896. 单调数列](https://leetcode-cn.com/problems/monotonic-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/monotonic-array/solution/wei-shi-yao-yi-ci-bian-li-yao-bi-liang-c-uglp/) | 简单 | 🤩🤩🤩🤩 |
| [905. 按奇偶排序数组](https://leetcode-cn.com/problems/sort-array-by-parity/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sort-array-by-parity/solution/by-ac_oier-nuz7/) | 简单 | 🤩🤩🤩 |
| [919. 完全二叉树插入器](https://leetcode.cn/problems/complete-binary-tree-inserter/) | [LeetCode 题解链接](https://leetcode.cn/problems/complete-binary-tree-inserter/solution/by-ac_oier-t9dh/) | 中等 | 🤩🤩🤩🤩 |
| [921. 使括号有效的最少添加](https://leetcode.cn/problems/minimum-add-to-make-parentheses-valid/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-add-to-make-parentheses-valid/solution/by-ac_oier-9tn1/) | 中等 | 🤩🤩🤩🤩 |
| [929. 独特的电子邮件地址](https://leetcode.cn/problems/unique-email-addresses/) | [LeetCode 题解链接](https://leetcode.cn/problems/unique-email-addresses/solution/by-ac_oier-d3zu/) | 简单 | 🤩🤩🤩 |
| [944. 删列造序](https://leetcode.cn/problems/delete-columns-to-make-sorted/) | [LeetCode 题解链接](https://leetcode.cn/problems/delete-columns-to-make-sorted/solution/by-ac_oier-smoz/) | 简单 | 🤩🤩🤩 |
| [946. 验证栈序列](https://leetcode.cn/problems/validate-stack-sequences/) | [LeetCode 题解链接](https://leetcode.cn/problems/validate-stack-sequences/solution/by-ac_oier-84qd/) | 中等 | 🤩🤩🤩🤩 |
Expand Down
13 changes: 5 additions & 8 deletions LeetCode/31-40/31. 下一个排列(中等).md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ Tag : 「模拟」、「数学」

---

### 朴素解法
### 模拟

找下一个排列的数大家可以先想想大脑来是怎么完成这个找数的过程的。
找下一个排列的数大家可以先想想大脑来是怎么完成这个找数的过程的。

**我们会尽可能的将低位的数字变大,这样才符合「下一个排列」的定义。**

Expand Down Expand Up @@ -80,8 +80,7 @@ Tag : 「模拟」、「数学」
```Java
class Solution {
public void nextPermutation(int[] nums) {
int n = nums.length;
int k = n - 1;
int n = nums.length, k = n - 1;
while (k - 1 >= 0 && nums[k - 1] >= nums[k]) k--;
if (k == 0) {
reverse(nums, 0, n - 1);
Expand All @@ -94,9 +93,7 @@ class Solution {
}
void reverse(int[] nums, int a, int b) {
int l = a, r = b;
while (l < r) {
swap(nums, l++, r--);
}
while (l < r) swap(nums, l++, r--);
}
void swap(int[] nums, int a, int b) {
int c = nums[a];
Expand All @@ -105,7 +102,7 @@ class Solution {
}
}
```
* 时间复杂度:对数组线性遍历。复杂度为 $O(n)$
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---
Expand Down
103 changes: 103 additions & 0 deletions LeetCode/921-930/921. 使括号有效的最少添加(中等).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
### 题目描述

这是 LeetCode 上的 **[921. 使括号有效的最少添加](https://leetcode.cn/problems/minimum-add-to-make-parentheses-valid/solution/by-ac_oier-9tn1/)** ,难度为 **中等**

Tag : 「模拟」



只有满足下面几点之一,括号字符串才是有效的:

* 它是一个空字符串,或者
* 它可以被写成 `AB` (`A` 与 `B` 连接), 其中 `A` 和 `B` 都是有效字符串,或者
* 它可以被写作 (`A`),其中 `A` 是有效字符串。

给定一个括号字符串 `s` ,移动 `N` 次,你就可以在字符串的任何位置插入一个括号。

* 例如,如果 `s = "()))"` ,你可以插入一个开始括号为 `"(()))"` 或结束括号为 `"())))"`

返回 为使结果字符串 `s` 有效而必须添加的最少括号数。


示例 1:
```
输入:s = "())"
输出:1
```
示例 2:
```
输入:s = "((("
输出:3
```

提示:
* $1 <= s.length <= 1000$
* `s` 只包含 `'('` 和 `')'` 字符

---

### 模拟

一个介绍过很多次的做法 : 将「有效括号问题」转化为「分值有效性」的数学判定。

使用 `score` 代指处理过程中的得分,将 `(` 记为 `+1`,将 `)` 记为 `-1`

一个有效的括号应当在整个过程中不出现负数,因此一旦 `score` 出现负数,我们需要马上增加 `(` 来确保合法性;当整个 `s` 处理完后,还需要添加 `socre` 等同的 `)` 来确保合法性。

Java 代码:
```Java
class Solution {
public int minAddToMakeValid(String s) {
int score = 0, ans = 0;
for (char c : s.toCharArray()) {
score += c == '(' ? 1 : -1;
if (score < 0) {
score = 0; ans++;
}
}
return ans + score;
}
}
```
TypeScript 代码:
```TypeScript
function minAddToMakeValid(s: string): number {
let scroe = 0, ans = 0
for (const c of s) {
scroe += c == '(' ? 1 : -1
if (scroe < 0) {
scroe = 0; ans++
}
}
return ans + scroe
};
```
Python 代码:
```Python
class Solution:
def minAddToMakeValid(self, s: str) -> int:
score, ans = 0, 0
for c in s:
score += 1 if c == '(' else -1
if score < 0:
score = 0
ans += 1
return ans + score
```
* 时间复杂度:$O(n)$
* 空间复杂度:使用 `charAt` 代替 `toCharArray` 操作,复杂度为 $O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.921` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

这是 LeetCode 上的 **[面试题 17.19. 消失的两个数字](https://leetcode.cn/problems/missing-two-lcci/solution/by-ac_oier-pgeh/)** ,难度为 **困难**。

Tag : 「数学」
Tag : 「数学」、「位运算」



Expand Down Expand Up @@ -78,6 +78,78 @@ class Solution:

---

### 异或

另外一类求解方法是利用「异或」+「lowbit」。

由于我们明确了是在 $[1, n + 2]$ 中缺失了两个数,我们可以先通过异或 $[1, n + 2]$ 以及所有的 $nums[i]$ 来得到缺失两个数值异或和 `t`。

我们知道异或结果二进制表示为 $1$ 代表了两缺失值该位置数值不同(一个该位置 $0$,另一个该位置为 $1$),我们可以根据异或和 `t` 中任意一位为 $1$ 的位置来将两个缺失值划分到两组中。

更加优雅的方式是使用 `lowbit` 操作:`d = t & -t` 可快速得到只保留 `t` 中最低位 `1` 的对应数值。

随后将 $[1, n + 2]$ 中满足 `i & d != 0` 的所有 `i`(含义为对应位置为 $1$ 的数值)与 $nums[i]$ 中满足 `nums[i] & d != 0` 的所有 $nums[i]$(含义为对应位置为 $1$ 的数值) 进行异或,最终能够确定其中一个缺失值,再结合最开始的异或和 `t` 即可确定另外一个缺失值。

Java 代码:
```Java
class Solution {
public int[] missingTwo(int[] nums) {
int n = nums.length + 2, cur = 0;
for (int i = 1; i <= n; i++) cur ^= i;
for (int x : nums) cur ^= x;
int t = cur, d = cur & -cur;
cur = 0;
for (int i = 1; i <= n; i++) {
if ((d & i) != 0) cur ^= i;
}
for (int x : nums) {
if ((d & x) != 0) cur ^= x;
}
return new int[]{cur, t ^ cur};
}
}
```
TypeScript 代码:
```TypeScript
function missingTwo(nums: number[]): number[] {
let n = nums.length + 2, cur = 0
for (let i = 1; i <= n; i++) cur ^= i
for (let x of nums) cur ^= x
const t = cur, d = cur & -cur
cur = 0
for (let i = 1; i <= n; i++) {
if ((d & i) != 0) cur ^= i
}
for (let x of nums) {
if ((d & x) != 0) cur ^= x
}
return [cur, t ^ cur]
};
```
Python 代码:
```Python
class Solution:
def missingTwo(self, nums: List[int]) -> List[int]:
n, cur = len(nums) + 2, 0
for i in range(1, n + 1):
cur ^= i
for x in nums:
cur ^= x
t, d = cur, cur & -cur
cur = 0
for i in range(1, n + 1):
if d & i:
cur ^= i
for x in nums:
if d & x:
cur ^= x
return [cur, t ^ cur]
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.面试题 17.19` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
Expand Down