《代码随想录》Day 1
0. Introduction
可用工具
- 数据结构可视化https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
1. 数组理论基础
- 数组是存放在连续内存空间上的相同类型数据的集合,因为数组内存空间的地址是连续的,所以某一元素变动时,其他元素的内存空间地址可能也会变化
- 数组可以通过下标索引的方式获取到下标对应的数据,数组的下标从0开始
- 数组的元素不能删除,只能覆盖
2. Q704. 二分查找
题目描述:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
- 由于该数组是有序数组,并且数组中无重复元素,所以可用二分法更快筛查数组中target值
二分法第一种写法(左闭右闭)
每次用比较范围 [left, right] 的中点 mid 和target进行比较,若mid < target, 则更新比较范围为右半部分,left= mid+1
class Solution:
def search(self, nums: List[int], target: int) -> int:
#定义target在左闭右闭区间内,保证边界的数也能被选上,且保证left=right的情况也能被讨论
left = 0
right = len(nums)-1
while left <= right: #用<=,保证left=right的情况也能被讨论
mid = left + (right-left)//2 #不用(right+left)//2是防止左右的值过大溢出
if mid == target:
return mid
elif mid < target: #则搜索右半边
left = mid + 1
elif mid > target: #则搜索左半边
right = mid -1
else: #没找到目标值
return -1
二分法第二种写法(左闭右开)
若将搜索区间定义为左闭右开区间,则
- while条件会变为while left < right (不会等于了)
- mid > target 时,更新 right 为 mid
class Solution:
def search(self, nums: List[int], target: int) -> int:
#定义target在左闭右开区间内
left = 0
right = len(nums) #因右为开区间
while left < right: #用<,因left=right在[left,right)中无意义
mid = left + (right-left)//2 #不用(right+left)//2是防止左右的值过大溢出
if mid == target:
return mid
elif mid < target: #则搜索右半边
left = mid + 1
elif mid > target: #则搜索左半边
right = mid
else: #没找到目标值
return -1
3. Q27. 移除元素
给定数组 nums 和一个值 val,需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度,元素的顺序可以改变。且不需要考虑数组中超出新长度后面的元素。
- 但数组的特点是不能删除,只能覆盖
暴力解法
两层while循环,第一层循环遍历数组中所有元素,若搜寻到相同元素,则第二个循环来更新数组,且需要将搜索的 i 也向前移动一位,搜索范围也往前走一位
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
i = 0
while i <n :
if nums[i] == val: #若搜索到匹配元素
j = i+1
while j < n: #将数组整体前移覆盖
nums[j-1] = nums[j]
j += 1
i -= 1 #i需要往前一位,因为i及以后的数值都向前移动了一位
n -= 1 #此时数组的大小也减少一位
i += 1
return n
双指针法
分为快慢指针,快指针a用来遍历数组中每一个数,若val != nums[a],则把该数拷贝到慢指针b所指的位置,随后快慢指针同时往后移一位,这样就保证了慢指针指到的所有数都为想要的数
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
a = 0
b = 0
while a < len(nums):
if nums[a] != val:
nums[b] = nums[a]
b += 1 #b只有搜索到不等于val的数时才+1,所以在循环里加
a += 1 #a每次都要+1,所以在循环外加
return b