基础知识
- 数组定义:数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
- 因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。数组的元素是不能删的,只能覆盖。
- C++中二维数组在地址空间上是连续的
704. 二分查找
LC链接:704
1、题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
2、思路:二分法模版题
(1)前提
- 有序
- 无重复元素
(2)左闭右闭
def binary_search(nums: list[int], target: int) -> int:
"""二分查找(双闭区间)"""
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
i, j = 0, len(nums) - 1
# 循环,当搜索区间为空时跳出(当 i > j 时为空)
while i <= j:
# 理论上 Python 的数字可以无限大(取决于内存大小),无须考虑大数越界问题
m = (i + j) // 2 # 计算中点索引 m
if nums[m] < target:
i = m + 1 # 此情况说明 target 在区间 [m+1, j] 中
elif nums[m] > target:
j = m - 1 # 此情况说明 target 在区间 [i, m-1] 中
else:
return m # 找到目标元素,返回其索引
return -1 # 未找到目标元素,返回 -1
3、代码
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while right >= left:
mid = left + (right - left) // 2
if nums[mid]>target:
right = mid - 1
elif nums[mid]<target:
left = mid + 1
else:
return mid
return -1
- 时间复杂度:O(log n) 每次缩小一半范围 n/2 n/4 n/8 一直到 1 就是logn
- 空间复杂度:O(1) 没有定义数组,只使用了变量
977.有序数组的平方
LC链接:977
1、题目描述
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序
进阶:
请你设计时间复杂度为 O(n) 的算法解决本问题
2、思路
(1)暴力法
先平方然后sort
平方时间复杂度o(n)
sort时间复杂度on(logn)
(2)双指针
因为原来数组是排好顺序的,平方之后最小值(负数)有可能变为最大值,但是平方后的最大值一定在原数组的两端
3、代码
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# 因为原来数组是排好顺序的,平方之后最小值(负数)有可能变为最大值,但是平方后的最大值一定在原数组的两端
# 创建一个结果数组
res = [0]*(len(nums))
# 定义三个指针
left = 0 # 原数组左边
right = len(nums) - 1 # 原数组右边
p = right # 新数组右边
while left <= right:
if nums[left] ** 2 >= nums[right]**2:
res[p] = nums[left] ** 2
left += 1
p -= 1
else:
res[p] = nums[right] ** 2
right -= 1
p -= 1
return res