数组

704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果 target 存在返回下标,否则返回 -1

你必须编写一个具有 O(log n) 时间复杂度的算法。

示例 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

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

TODO:

  • 补充所有二分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def search(self, nums: List[int], target: int) -> int:
l, r, m = 0, len(nums)-1, len(nums)//2
while l <= r:
m = (r+l)//2
print(f"{l=},{r=},{m=}")
if nums[m] == target:
return m
else:
if nums[m] < target:
l = m + 1
else:
r = m - 1
return -1

27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

用户评测:

评测机将使用以下代码测试您的解决方案:

int[] nums = […]; // 输入数组
int val = …; // 要移除的值
int[] expectedNums = […]; // 长度正确的预期答案。
// 它以不等于 val 的值排序。

int k = removeElement(nums, val); // 调用你的实现

assert k == expectedNums.length;
sort(nums, 0, k); // 排序 nums 的前 k 个元素
for (int i = 0; i < actualLength; i++) {
assert nums[i] == expectedNums[i];
}

如果所有的断言都通过,你的解决方案将会 通过

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,,]
解释:你的函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,,,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 50
  • 0 <= val <= 100
1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
if len(nums) == 0:
return 0
s, f = 0, 0
while f < len(nums):
# 快指针把非val丢过来
if nums[f] != val:
nums[s] = nums[f]
s += 1
f += 1
return s

977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 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 <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 已按 非递减顺序 排序

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
length = len(nums)
ans = [0] * length
l, r, addp = 0, length-1, length-1
while l <= r:
l2 = nums[l] * nums[l]
r2 = nums[r] * nums[r]
if l2 > r2:
ans[addp] = l2
l += 1
else:
ans[addp] = r2
r -= 1
addp -= 1
return ans

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度**。**如果不存在符合条件的子数组,返回 0

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

  • 1 <= target <= 10^9
  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^4

进阶:

  • 如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
minsubl = 1e6
s, f = 0, 0
sumfs = 0
for f in range(len(nums)):
sumfs += nums[f]
while sumfs >= target:
subl = f - s +1
if subl < minsubl:
minsubl = subl
sumfs -= nums[s]
s += 1
return minsubl if minsubl != 1e6 else 0

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
# 需要注意的是,方法三中使用乘法运算符创建的二维列表可能会出现问题,因为复制的是引用,所有内部的空列表实际上是同一个对象。这意味着任何对其中一个内部列表的修改都会同时反映到其他内部列表中。因此,在实际应用中,应该避免使用方法三。
ans = [[0 for _ in range(n)] for _ in range(n)]
if n % 2 == 1:
ans[n//2][n//2]= n * n
startx, starty = 0, 0
lastx, lasty = n//2, n//2
num = 1
# 边起始
x, y = 0,0
while startx < lastx:
# North
x, y = startx, starty
for j in range(x, n-x-1):
ans[y][j] = num
num += 1
# East
x, y = n-startx-1, starty
for i in range(y, n-y-1):
ans[i][x] = num
num += 1
# South
x, y = n-startx-1, n-starty-1
for j in range(x, n-x-1, -1):
ans[y][j] = num
num += 1
# West
x, y = startx, n-starty-1,
for i in range(y, n-y-1, -1):
ans[i][x] = num
num += 1
startx += 1
starty += 1
return ans