今日学习的文章链接和视频链接
● 自己看到题目的第一想法
● 看完代码随想录之后的想法
● 自己实现过程中遇到哪些困难
● 今日收获,记录一下自己的学习时长
状态
思路理解完成 30%
代码debug完成 60%
代码模板总结并抽象出来 100%
题目
704 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
状态:进度 45%
思路:要仔细debug一下闭区间、左开右闭的写法。
27. 移除元素
题目建议: 暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握,至于拓展题目可以先不看。
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
状态:60%
977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解:
https://www.bilibili.com/video/BV1QB4y1D7ep
状态:45%
学习记录
数组
1、在内存中的存储方式
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。
数组的元素是不能删的,只能覆盖。
根据 左闭右开,左闭右闭 两种区间规则 写出来的二分法
二分查找法的前提
- 数组为有序数组
- 同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的
时间投入
两个小时过了一下两天的题目。
找到了一点点感觉。思路都是对的,现在重点训练落地正确准确率。(其实就是深度理解和背模板)
代码模板
二分查找
闭区间
# 闭区间
def binary_search(nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1 # 闭区间 [left, right]
while left <= right: # 终止条件:left > right
mid = left + (right - left) // 2 # 避免溢出
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1 # 目标在右半部分
else:
right = mid - 1 # 目标在左半部分
return -1 # 未找到
关键点:
• 循环条件:left <= right
(闭区间)。
• 中间值计算:mid = left + (right - left) // 2
(避免 (left + right)
溢出)。
• 返回值:找到时返回 mid
,否则返回 -1
。
左闭右开
def binary_search(nums: list[int], target: int) -> int:
left, right = 0, len(nums) # 初始化右开区间 [left, right)
while left < right: # 终止条件:left == right
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1 # 目标在右半部分 [mid+1, right)
else:
right = mid # 目标在左半部分 [left, mid)
return -1 # 未找到
关键区别:
- 初始区间:
right = len(nums)
(开区间,不包含len(nums)
)。 - 循环条件:
left < right
(终止时left == right
)。 - 右边界更新:
right = mid
(因为right
本身是开区间,不包含mid
)。 - 返回值:未找到时返回
-1
。
特性 | 闭区间 [left, right] | 左闭右开 [left, right) | 左开右闭 (left, right] |
---|---|---|---|
初始化 | right = len(nums) - 1 | right = len(nums) | left = -1 |
循环条件 | left <= right | left < right | left < right |
中值计算 | mid = left + (right - left)//2 | 同上 | mid = left + (right - left +1)//2 |
更新左边界 | left = mid + 1 | left = mid + 1 | left = mid |
更新右边界 | right = mid - 1 | right = mid | right = mid - 1 |
优势 | 逻辑直观,易理解 | 避免 right 越界,代码简洁 | 适合右侧逼近问题 |