数组的基础理论
- 数组存储空间是连续的
- 数组的起始点是0
- 在数组中的元素是不能删的,而是通过覆盖把改元素“删除”
704. 二分查找
左闭右开方法:
1. 初始化right的时候是len(nums) 保持右区间开放
2. 使用while循环的时候判断条件是 left < right,维持左闭右开区间;因为[1,1)是不合法的区间
3. 当nums[mid] > target,中间值 > 目标值时;right = mid 将 right
设为 mid
是为了在下一次搜索时排除当前的 mid
位置。
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
using [) left open right close method
"""
left = 0
right = len(nums)
# since we use [) method, which right border is close, thus left can't equal to right
while left < right:
mid = (left+right)//2
# if the nums[mid] value is bigger than target
if nums[mid] > target:
# this means we should search left part, reduce right value
right = mid # since right is close border, we didn't contain middle value at last search
# to small
elif nums[mid] < target:
# menas we should search right part, increase left value
left = mid + 1
# nums[mid] == target; return mid, which is target index
else:
return mid
# if we excuete the while loop doesn't return, measn target is not in our list
return -1
左闭右闭方法:
1. 保证区间是在 left <= right; 初始化right应该是 len(nums) - 1;[1,1]是个合法的区间
2. 当 nums[mid] > target时 right = mid-1; mid值已经被检查过了所以是 mid-1
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
# left close right close [left,right]
left = 0
right = len(nums) - 1
# maitain [left,right] rule
while left <= right:
mid = (left+right)//2
# if mid > target
if nums[mid] > target:
# reduce to left part to search answer
right = mid - 1
# if mid < target
elif nums[mid] < target:
# reduce to right part to search answer
left = mid + 1
# mid == target
else:
return mid
return -1
27. 移除元素
快慢指针方法:
1. 设置两个指针一个快指针一个慢指针都从头开始遍历
2. 由于快指针要走完整个数组,所以当快指针走完数组时,循环结束
3. 快指针每次循环都在移动,而慢指针只有在快指针指向的值不等于目标值时移动
4. 在慢指针移动的时候nums[slow] = nums[fast];让快指针的值赋值给慢指针,这样当慢指针指向目标值的时候,快指针已经不在目标值的位置,从而可以让慢指针覆盖掉目标值达到更新数组的目的
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
# two pointer method slow and fast
slow = 0
fast = 0
# iterate the array
while fast < len(nums):
# if fast pointer it's not met with val
if nums[fast] != val:
# let nums[fast] value give to nums[slow]; this way we can update the array
nums[slow] = nums[fast]
# slow pointer move
slow += 1
# fast pointer always move until end of the list
fast += 1
# return slow it's the update array lenegth
return slow
暴力破解
1. 在写暴力破解的时候一开始使用的是双层for loop去来暴力破解,不过我发现好像因为外层for loop即使使用i-=1的方法也无法避免会跳过元素从而让答案错误,所以我认为在python中是否这题的暴力破解只能使用一层while循环一层for循环去得到正确答案?
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
i = 0
size = len(nums)
# iterate the whole array
while i < size:
# if element == value
if nums[i] == val:
# update the array
for j in range(i+1,size):
nums[j-1] = nums[j]
size -= 1
# sicne we reduce size of the array, i value also need decrese by 1, otherwise we will skip elements
i -= 1
i+=1
return size
977. 有序的数组平方(双指针)
1. 定义两个指针一个指向数组起始的地方,另一个指向数组末尾
2。 定义一个新的数组(result[])来存储答案,以及定义一个变量k来存储新数组的下标
3. 由于题目是要按照数字大小排序返回,这里我们用从新数组末尾添加的方式
4. 循环条件是 left <= right, 因为我们要考虑两个指针最后是要碰到一起返回最后一个元素的
5. 通过两个指针指向不同的元素去判断哪一个元素平方大并把改指针的值传递给result[k]
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# using two pointer method
left = 0
right = len(nums) - 1
# new array
result = [0] * len(nums)
k = len(nums)-1 # this is new array index keeper
# iterate array
while left <= right:
# determine which pointer has larger value
if nums[right]*nums[right] > nums[left] * nums[left]:
# nums[right] has larger value put it into new array
result[k] = nums[right]*nums[right]
k -= 1
right -= 1
# we use else to detemine if nums[left]**2 > nums[right]**2 and if they are equal
else:
# nums[left] has larger value this time
result[k] = nums[left] * nums[left]
k -= 1
left += 1
return result