-
Notifications
You must be signed in to change notification settings - Fork 956
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
23cea7e
commit bded865
Showing
4 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
### 题目描述 | ||
|
||
这是 LeetCode 上的 **[1051. 高度检查器](https://leetcode.cn/problems/height-checker/solution/by-ac_oier-8xoj/)** ,难度为 **简单**。 | ||
|
||
Tag : 「排序」、「模拟」 | ||
|
||
|
||
|
||
学校打算为全体学生拍一张年度纪念照。根据要求,学生需要按照 非递减 的高度顺序排成一行。 | ||
|
||
排序后的高度情况用整数数组 `expected` 表示,其中 `expected[i]` 是预计排在这一行中第 `i` 位的学生的高度(下标从 $0$ 开始)。 | ||
|
||
给你一个整数数组 `heights`,表示 当前学生站位 的高度情况。`heights[i]` 是这一行中第 `i` 位学生的高度(下标从 $0$ 开始)。 | ||
|
||
返回满足 `heights[i] != expected[i]` 的 下标数量 。 | ||
|
||
示例: | ||
``` | ||
输入:heights = [1,1,4,2,1,3] | ||
输出:3 | ||
解释: | ||
高度:[1,1,4,2,1,3] | ||
预期:[1,1,1,2,3,4] | ||
下标 2 、4 、5 处的学生高度不匹配。 | ||
``` | ||
示例 2: | ||
``` | ||
输入:heights = [5,1,2,3,4] | ||
输出:5 | ||
解释: | ||
高度:[5,1,2,3,4] | ||
预期:[1,2,3,4,5] | ||
所有下标的对应学生高度都不匹配。 | ||
``` | ||
示例 3: | ||
``` | ||
输入:heights = [1,2,3,4,5] | ||
输出:0 | ||
解释: | ||
高度:[1,2,3,4,5] | ||
预期:[1,2,3,4,5] | ||
所有下标的对应学生高度都匹配。 | ||
``` | ||
|
||
提示: | ||
* $1 <= heights.length <= 100$ | ||
* $1 <= heights[i] <= 100$ | ||
|
||
--- | ||
|
||
### 排序 | ||
|
||
先排序得到目标序列,再将目标序列和原序列进行逐一对比,得到答案。 | ||
|
||
排序部分,可以使用复杂度为 $O(n\log{n})$ 的双轴快排,也可以利用数据范围为 $100$,利用计数排序思想来构建目标序列,复杂度为 $O(C + n)$。 | ||
|
||
代码(快排 $P1$,计数排序 $P2$): | ||
```Java | ||
class Solution { | ||
public int heightChecker(int[] heights) { | ||
int[] t = heights.clone(); | ||
Arrays.sort(t); | ||
int n = heights.length, ans = 0; | ||
for (int i = 0; i < n; i++) { | ||
if (t[i] != heights[i]) ans++; | ||
} | ||
return ans; | ||
} | ||
} | ||
``` | ||
|
||
- | ||
|
||
```Java | ||
class Solution { | ||
public int heightChecker(int[] heights) { | ||
int[] cnts = new int[110]; | ||
for (int i : heights) cnts[i]++; | ||
int n = heights.length, ans = 0; | ||
int[] t = new int[n]; | ||
for (int i = 0, j = 0; i < 110; i++) { | ||
while (cnts[i]-- > 0) t[j++] = i; | ||
} | ||
for (int i = 0; i < n; i++) { | ||
if (t[i] != heights[i]) ans++; | ||
} | ||
return ans; | ||
} | ||
} | ||
``` | ||
* 时间复杂度:排序复杂度为 $O(n\log{n})$(快排)或者为 $O(C + n)$(计数排序),统计答案复杂度为 $O(n)$。整体复杂度为 $O(n\log{n})$(快排)或 $O(C + n)$(计数排序) | ||
* 空间复杂度:$O(\log{n})$ | ||
|
||
--- | ||
|
||
### 最后 | ||
|
||
这是我们「刷穿 LeetCode」系列文章的第 `No.1051` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 | ||
|
||
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 | ||
|
||
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 | ||
|
||
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
### 题目描述 | ||
|
||
这是 LeetCode 上的 **[1737. 满足三条件之一需改变的最少字符数](https://leetcode.cn/problems/change-minimum-characters-to-satisfy-one-of-three-conditions/solution/by-ac_oier-vs5u/)** ,难度为 **中等**。 | ||
|
||
Tag : 「枚举」、「计数」、「模拟」 | ||
|
||
|
||
|
||
给你两个字符串 `a` 和 `b` ,二者均由小写字母组成。 | ||
|
||
一步操作中,你可以将 `a` 或 `b` 中的 任一字符 改变为 任一小写字母 。 | ||
|
||
操作的最终目标是满足下列三个条件 之一 : | ||
* `a` 中的 每个字母 在字母表中 **严格小于** `b` 中的 每个字母 。 | ||
* `b` 中的 每个字母 在字母表中 **严格小于** `a` 中的 每个字母 。 | ||
* `a` 和 `b` 都 由 同一个 字母组成。 | ||
|
||
返回达成目标所需的 最少 操作数。 | ||
|
||
示例 1: | ||
``` | ||
输入:a = "aba", b = "caa" | ||
输出:2 | ||
解释:满足每个条件的最佳方案分别是: | ||
1) 将 b 变为 "ccc",2 次操作,满足 a 中的每个字母都小于 b 中的每个字母; | ||
2) 将 a 变为 "bbb" 并将 b 变为 "aaa",3 次操作,满足 b 中的每个字母都小于 a 中的每个字母; | ||
3) 将 a 变为 "aaa" 并将 b 变为 "aaa",2 次操作,满足 a 和 b 由同一个字母组成。 | ||
最佳的方案只需要 2 次操作(满足条件 1 或者条件 3)。 | ||
``` | ||
示例 2: | ||
``` | ||
输入:a = "dabadd", b = "cda" | ||
输出:3 | ||
解释:满足条件 1 的最佳方案是将 b 变为 "eee" 。 | ||
``` | ||
|
||
提示: | ||
* $1 <= a.length, b.length <= 10^5$ | ||
* `a` 和 `b` 只由小写字母组成 | ||
|
||
--- | ||
|
||
### 计数 + 枚举 | ||
|
||
使用 `c1` 和 `c2` 对字符串 `a` 和 `b` 分别进行词频统计,记字符串 `a` 和 `b` 的长度为 $n$ 和 $m$。 | ||
|
||
然后枚举字符 $i$,分别对三种情况的修改次数进行统计: | ||
|
||
1. 对应条件 $1$:目的是要将字符串 `a` 中所有的字符变得「严格小于」字符 $i$,将字符串 `b` 中的所有字符变成「不小于/大于等于」字符 $i$。 | ||
这可以分别统计 `a` 中大小满足「大于等于」字符 $i$ 的字符数量,以及 `b` 中大小满足「小于」字符 $i$ 数量,两者之和即是满足该条件的最小修改次数。 | ||
注意,当 $i = 0$(含义为枚举到小写字母 $a$)时,需要跳过,因为不存在值大小「严格小于」字母 $a$ 的字符,即无法做到将某个字符串替换成所有字符都「严格小于」字母 $a$; | ||
2. 对应条件 $2$:与条件 $1$ 同理; | ||
3. 对应条件 $3$:如果要将两字符的所有字符都变成 $i$,其中字符串 `a` 要修改的字符数为 $ca = n - c1[i]$,字符串 `b` 要修改的字符数为 $cb = m - c2[i]$,总修改次数为 $ca + cb$。 | ||
|
||
枚举完所有的字符 $i$ 后,统计到的所有修改次数的最小值即是答案。 | ||
|
||
代码: | ||
```Java | ||
class Solution { | ||
public int minCharacters(String a, String b) { | ||
int n = a.length(), m = b.length(), ans = 0x3f3f3f3f; | ||
int[] c1 = new int[26], c2 = new int[26]; | ||
for (char c : a.toCharArray()) c1[c - 'a']++; | ||
for (char c : b.toCharArray()) c2[c - 'a']++; | ||
for (int i = 0; i < 26 && ans != 0; i++) { | ||
// 3 | ||
int ca = n - c1[i], cb = m - c2[i]; | ||
ans = Math.min(ans, ca + cb); | ||
if (i == 0) continue; | ||
int r1 = 0, r2 = 0; | ||
// 1 | ||
for (int j = i; j < 26; j++) r1 += c1[j]; | ||
for (int j = 0; j < i; j++) r1 += c2[j]; | ||
// 2 | ||
for (int j = i; j < 26; j++) r2 += c2[j]; | ||
for (int j = 0; j < i; j++) r2 += c1[j]; | ||
ans = Math.min(ans, Math.min(r1, r2)); | ||
} | ||
return ans; | ||
} | ||
} | ||
``` | ||
* 时间复杂度:统计词频的复杂度为 $O(n + m)$,统计答案的复杂度为 $O(C^2)$,其中 $C = 26$ 为字符集大小 | ||
* 空间复杂度:$O(C)$ | ||
|
||
--- | ||
|
||
### 最后 | ||
|
||
这是我们「刷穿 LeetCode」系列文章的第 `No.1737` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 | ||
|
||
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 | ||
|
||
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 | ||
|
||
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 | ||
|