参考文献(代码随想录)
一、704. 二分查找. - 力扣(LeetCode)(数组是有序序列)
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
解题思路:
1. 暴力枚举:一个循环,判断循环到的元素是否为目标值,如果是则输出并返回这个元素,反之返回-1
class Solution(object): def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ n = len(nums) # 取nums数组的长度 for i in range(n): if nums[i] == target: # 遇到目标值直接返回并退出 return i return -1 # 如果循环完了,还没有找到,则返回-1
2. 二分查找: 第一种写法:左指针 = 0,右指针 == 数组长度 - 1
第二种写法:左指针 = -1,右指针 == 数组长度(虚拟指针)
第一种:
class Solution(object): def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ n = len(nums) # 取nums数组的长度 left = 0 right = n - 1 while left <= right: mid = (left + right) // 2 # 注意mid要写在循环里面,才能实现二分的动态查找 if nums[mid] == target: # 遇到目标值直接返回并退出 return mid elif nums[mid] > target: # [2, 4, 5, 6, 7] 假设mid = 2(下标), Target = 4 # left Target nums[mid] right # nums[mid] > Target, 所以要缩小范围 # 因为nums数组左右都可以取到,所以在判断是否加一或者减一时看数组能不能取到,如果取到,说明该点已经被比较过了 right = mid - 1 # 注意:这里处理不好,会造成死循环,如何是 else: left = mid + 1 return -1 # 如果循环完了,还没有找到,则返回-1
第二种:
class Solution(object): def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ n = len(nums) # 取nums数组的长度 left = -1 right = n while left + 1 < right: mid = (left + right) // 2 if nums[mid] >= target: # 找到一个比Target大的第一个数,或者是等于Target right = mid else: left = mid if right == n or nums[right] != target: #防止下标越界和判断是否找 return - 1 return right
二、27. 移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
双指针:一个慢,一个快,慢的那个指针是寻找val元素,而快指针是寻找不是val元素,然后在把块指针对应的值赋值给慢指针
class Solution(object): def removeElement(self, nums, val): """ :type nums: List[int] :type val: int :rtype: int """ slow = 0 for i in range(len(nums)): if nums[i] != val: nums[slow] = nums[i] slow += 1 return slow