思路:
首先看到题目前提条件为:1有序数组,2无重复元素,如果有重复元素那么使用二分法查找元素的下标可能不是唯一的;满足这两个条件就可以考虑使用二分法。
使用二分法首先要确定区间的定义,常用的两种区间定义为左闭右闭 [left, right] 和左闭右开 [left, right),二者的写法也有不同。
第一种,左闭右闭即 [left, right]
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1 # 定义target在左闭右闭的区间里,[left, right]
while left <= right:
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle - 1 # target在左区间,所以[left, middle - 1]
elif nums[middle] < target:
left = middle + 1 # target在右区间,所以[middle + 1, right]
else:
return middle # 数组中找到目标值,直接返回下标
return -1 # 未找到目标值
第二种,左闭右开即 [left, right)
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) # 定义target在左闭右开的区间里,即:[left, right)
while left < right: # 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle # target 在左区间,在[left, middle)中
elif nums[middle] < target:
left = middle + 1 # target 在右区间,在[middle + 1, right)中
else:
return middle # 数组中找到目标值,直接返回下标
return -1 # 未找到目标值
思路:
在数组中,由于存储地址的连续,故删除某一元素并不是真的在这个地址上删除了该元素,而是覆写了该元素;在数组中删除一个元素的时间复杂度并不是O(1)而是O(n),这是因为从这一元素开始直到倒数第二个元素都被覆写了一遍。此题又可分为暴力解法和双指针法。
暴力解法:嵌套两层for循环,时间复杂度为O(n²),空间复杂度O(1)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
i = 0
while i < n:
if nums[i] == val:
for j in range(i+1, n):
nums[j-1] = nums[j]
n -= 1
else:
i += 1
return n
双指针法:时间复杂度O(n)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
slow, fast = 0, 0 # 快慢指针
while fast < n: # 当fast=n时数组越界
if nums[fast] != val: # slow指针收集不等于val的值
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
今天是第一次记录自己的博客,以后加油!