auto commit
This commit is contained in:
parent
293854f695
commit
43fdefc0e8
|
@ -56,10 +56,10 @@
|
||||||
|
|
||||||
二分查找思想简单,但是在实现时有一些需要注意的细节:
|
二分查找思想简单,但是在实现时有一些需要注意的细节:
|
||||||
|
|
||||||
1. 在计算 mid 时不能使用 mid = (l + h) / 2 这种方式,因为 l + h 可能会导致加法溢出,应该使用 mid = l + (h - l) / 2 。
|
1. 在计算 mid 时不能使用 mid = (l + h) / 2 这种方式,因为 l + h 可能会导致加法溢出,应该使用 mid = l + (h - l) / 2。
|
||||||
|
|
||||||
2. 对 h 的赋值和循环条件有关,当循环条件为 l <= h 时,h = mid - 1;当循环条件为 l < h 时,h = mid。
|
2. 对 h 的赋值和循环条件有关,当循环条件为 l <= h 时,h = mid - 1;当循环条件为 l < h 时,h = mid。
|
||||||
解释如下:在循环条件为 l <= h 时,如果 h = mid,会出现循环无法退出的情况,例如 l = 1,h = 1,此时 mid 也等于 1,如果此时继续执行 h = mid ,那么就会无限循环;在循环条件为 l < h ,如果 h = mid - 1,会错误跳过查找的数,例如对于数组 1,2,3 ,要查找 1 ,最开始 l = 0,h = 2,mid = 1,判断 key < arr[mid] 执行 h = mid - 1 = 0,此时循环退出,直接把查找的数跳过了。
|
解释如下:在循环条件为 l <= h 时,如果 h = mid,会出现循环无法退出的情况,例如 l = 1,h = 1,此时 mid 也等于 1,如果此时继续执行 h = mid,那么就会无限循环;在循环条件为 l < h,如果 h = mid - 1,会错误跳过查找的数,例如对于数组 [1,2,3],要查找 1,最开始 l = 0,h = 2,mid = 1,判断 key < arr[mid] 执行 h = mid - 1 = 0,此时循环退出,直接把查找的数跳过了。
|
||||||
|
|
||||||
3. l 的赋值一般都为 l = mid + 1。
|
3. l 的赋值一般都为 l = mid + 1。
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ The coins can form the following rows:
|
||||||
Because the 4th row is incomplete, we return 3.
|
Because the 4th row is incomplete, we return 3.
|
||||||
```
|
```
|
||||||
|
|
||||||
题目描述:第 i 行摆 i 个,统计能够排列的行数。
|
题目描述:第 i 行摆 i 个,统计能够摆的行数。
|
||||||
|
|
||||||
返回 h 而不是 l,因为摆的硬币最后一行不能算进去。
|
返回 h 而不是 l,因为摆的硬币最后一行不能算进去。
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ public int singleNonDuplicate(int[] nums) {
|
||||||
int l = 0, h = nums.length - 1;
|
int l = 0, h = nums.length - 1;
|
||||||
while(l < h) {
|
while(l < h) {
|
||||||
int m = l + (h - l) / 2;
|
int m = l + (h - l) / 2;
|
||||||
if(m % 2 == 1) m--; // 保证 l/h/m 都在偶数位,使得查找区间大小一直都是 奇数
|
if(m % 2 == 1) m--; // 保证 l/h/m 都在偶数位,使得查找区间大小一直都是奇数
|
||||||
if(nums[m] == nums[m + 1]) l = m + 2;
|
if(nums[m] == nums[m + 1]) l = m + 2;
|
||||||
else h = m;
|
else h = m;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ public int singleNonDuplicate(int[] nums) {
|
||||||
|
|
||||||
因为最小的孩子最容易得到满足,因此先满足最小孩子。给一个孩子的饼干应当尽量小又能满足该孩子,这样大饼干就能拿来给满足度比较大的孩子。
|
因为最小的孩子最容易得到满足,因此先满足最小孩子。给一个孩子的饼干应当尽量小又能满足该孩子,这样大饼干就能拿来给满足度比较大的孩子。
|
||||||
|
|
||||||
证明:假设在某次选择中,贪心策略选择给第 i 个孩子分配第 m 个饼干,并且第 i 个孩子满足度最小,第 m 个饼干为可以满足第 i 个孩子的最小饼干,利用贪心策略最终可以满足 k 个孩子。假设最优策略在这次选择中给 i 个孩子分配第 n 个饼干,并且这个饼干大于第 m 个饼干,那么最优策略最终需要满足大于 k 个孩子。我们发现使用第 m 个饼干去替代第 n 个饼干完全不影响后续的结果,因此贪心策略就是最优策略,因此贪心策略是最优的。
|
证明:假设在某次选择中,贪心策略选择给第 i 个孩子分配第 m 个饼干,并且第 i 个孩子满足度最小,第 m 个饼干为可以满足第 i 个孩子的最小饼干,利用贪心策略最终可以满足 k 个孩子。假设最优策略在这次选择中给 i 个孩子分配第 n 个饼干,并且这个饼干大于第 m 个饼干。我们发现使用第 m 个饼干去替代第 n 个饼干完全不影响后续的结果,因此不存在比贪心策略更优的策略,即贪心策略就是最优策略。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int findContentChildren(int[] g, int[] s) {
|
public int findContentChildren(int[] g, int[] s) {
|
||||||
|
@ -4884,11 +4884,9 @@ public int maxProduct(String[] words) {
|
||||||
# 参考资料
|
# 参考资料
|
||||||
|
|
||||||
- [Leetcode](https://leetcode.com/problemset/algorithms/?status=Todo)
|
- [Leetcode](https://leetcode.com/problemset/algorithms/?status=Todo)
|
||||||
- 剑指 Offer
|
|
||||||
- 程序员面试金典
|
|
||||||
- 编程之美
|
|
||||||
- 程序员代码面试指南
|
|
||||||
- 数据结构与算法分析
|
- 数据结构与算法分析
|
||||||
- 算法
|
- 算法
|
||||||
- 王道论坛计算机考研机试指南
|
- 剑指 Offer
|
||||||
|
- 编程之美
|
||||||
|
- 程序员代码面试指南
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user