0
点赞
收藏
分享

微信扫一扫

LeetCode 课程 Task02 学习打卡(2021年11月16日~11月17日)


第 02 天题目

0066. 加一

  • 标签:数组
  • 难度:简单

题目大意

给定一个非负整数数组,数组每一位对应整数的一位数字。计算整数 +1 后的结果。

解题思路

这道题把整个数组看成了一个整数,然后个位数 +1。问题的实质是利用数组模拟加法运算。

如果个位数不为 9 的话,直接把个位数 +1 就好。如果个位数为 9 的话,还要考虑进位。

具体步骤:

  1. 数组前补 0 位。
  2. 将个位数字进行 +1 计算。
  3. 遍历数组
  1. 如果该位数字 大于等于 10,则向下一位进 1,继续下一位判断进位。
  2. 如果该位数字 小于 10,则跳出循环。

代码

def plusOne(self, digits: List[int]) -> List[int]:
digits = [0] + digits
digits[len(digits)-1] += 1
for i in range(len(digits)-1,0,-1):
if digits[i] != 10:
break
else:
digits[i] = 0
digits[i-1] += 1

if digits[0] == 0:
return digits[1:]
else:
return digits

0724. 寻找数组的中心下标

  • 标签:数组
  • 难度:简单

题目大意

给定一个数组 nums,找到「左侧元素和」与「右侧元素和相等」的位置,若找不到,则返回 -1。

解题思路

两次遍历,第一次遍历先求出数组全部元素和。第二次遍历找到左侧元素和恰好为全部元素和一半的位置。

代码

class Solution:
def pivotIndex(self, nums: List[int]) -> int:
sum = 0
for i in range(len(nums)):
sum += nums[i]
curr_sum = 0
for i in range(len(nums)):
if curr_sum * 2 + nums[i] == sum:
return i
curr_sum += nums[i]
return -1

0189. 旋转数组

  • 标签:数组
  • 难度:中等

题目大意

给定一个数组,将数组中的元素向右移动 k 个位置。

解题思路

很容易想到的是用一个新数组,先保存原数组的后 k 个元素,再保存原数组的前 n-k 个元素。但题目要求不使用额外的数组空间,那么就需要在原数组上做操作。

我们可以先把整个数组翻转一下,这样后半段元素就到了前边,前半段元素就到了后边,只不过元素顺序是反着的。我们再从 k 位置分隔开,将 [0, k-1] 的元素和 [k, n-1] 的元素再翻转一下,就得到了最终结果。

具体步骤:

  1. 将数组 [0, n-1] 位置上的元素全部翻转
  2. 将数组 [0, k-1] 位置上的元素进行翻转
  3. 将数组 [k+1, n-1] 位置上的元素进行翻转

代码

class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k = k % n
self.reverse(nums, 0, n-1)
self.reverse(nums, 0, k-1)
self.reverse(nums, k, n-1)
def reverse(self, nums: List[int], left: int, right: int) -> None:
while left < right :
tmp = nums[left]
nums[left] = nums[right]
nums[right] = tmp
left += 1
right -= 1

第 03 天题目

​​0048. 旋转图像​​

  • 标签:数组
  • 难度:中等

题目大意

给定一个 n*n 的二维矩阵(代表图像)。将二维矩阵顺时针旋转 90°,要求不能使用额外的数组空间。

解题思路

如果使用额外数组空间的话,将对应元素存放到对应位置即可。如果不使用额外的数组空间,则需要观察每一个位置上的点最初位置和最终位置有什么规律。

对于矩阵中第 i 行的第 j 个元素,在旋转后,它出现在倒数第 i 列的第 j 个位置。即

​matrixnew[col][n−row−1] = matrix[row][col]​

而 ​​matrixnew[col][n-row-1]​​​ 的点经过旋转移动到了 ​​matrix[n−row−1][n−col−1]​​ 的位置。

​matrix[n−row−1][n−col−1]​​​ 位置上的点经过旋转移动到了 ​​matrix[n−col−1][row]​​ 的位置。

​matrix[n−col−1][row]​​​ 位置上的点经过旋转移动到了最初的 ​​matrix[row][col]​​ 的位置。

这样就形成了一个循环,我们只需要通过一个临时变量 tmp 就可以将循环中的点逐一进行交换。

另一种思路是利用翻转代替旋转。

原矩阵可以通过一次水平翻转+主对角线翻转得到旋转后的二维矩阵。具体可以参考代码。

代码

def rotate(self, matrix: List[List[int]]) -> None:
n = len(matrix)
for i in range(n//2):
for j in range(n):
matrix[i][j], matrix[n-i-1][j] = matrix[n-i-1][j], matrix[i][j]
for i in range(n):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

​​0054. 螺旋矩阵​​

  • 标签:数组
  • 难度:中等

题目大意

给定一个 m * n 大小的二维矩阵 matrix。要求按照顺时针旋转的顺序,返回矩阵中的所有元素。

解题思路

按照题意进行模拟。可以实现定义一下上、下、左、右的边界,然后按照逆时针的顺序从边界上依次访问元素。

当访问完当前边界之后,要更新一下边界位置,缩小范围,方便下一轮进行访问。

代码

class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
up, down, left, right = 0, len(matrix)-1, 0, len(matrix[0])-1
ans = []
while True:
for i in range(left, right + 1):
ans.append(matrix[up][i])
up += 1
if up > down:
break
for i in range(up, down + 1):
ans.append(matrix[i][right])
right -= 1
if right < left:
break
for i in range(right, left - 1, -1):
ans.append(matrix[down][i])
down -= 1
if down < up:
break
for i in range(down, up - 1, -1):
ans.append(matrix[i][left])
left += 1
if left > right:
break
return ans

​​0498. 对角线遍历​​

  • 标签:数组、矩阵、模拟
  • 难度:中等

题目大意

给你一个大小为 ​​m * n​​​ 的矩阵 ​​mat​​ 。

要求:以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

解题思路

这道题的关键是「找规律」和「考虑边界问题」。

找规律:

  • 当行号 + 列号为偶数时,遍历方向为从左下到右上。可以记为右上方向(-1, +1),即行号 -1,列号 +1。
  • 当行号 + 列号为奇数时,遍历方向为从右上到左下。可以记为左下方向(+1, -1),即行号 +1,列号 -1。

边界情况:

  • 向右上方向移动时:
  • 如果在最后一列,则向下方移动,即​​x += 1​​。
  • 如果在第一行,则向右方移动,即​​y += 1​​。
  • 其余情况想右上方向移动,即​​x -= 1​​​、​​y += 1​​。
  • 向左下方向移动时:
  • 如果在最后一行,则向右方移动,即​​y += 1​​。
  • 如果在第一列,则向下方移动,即​​x += 1​​。
  • 其余情况向左下方向移动,即​​x += 1​​​、​​y -= 1​​。

代码

class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
rows = len(mat)
cols = len(mat[0])
count = rows * cols
x, y = 0, 0
ans = []

for i in range(count):
ans.append(mat[x][y])

if (x + y) % 2 == 0:
# 最后一列
if y == cols - 1:
x += 1
# 第一行
elif x == 0:
y += 1
# 右上方向
else:
x -= 1
y += 1
else:
# 最后一行
if x == rows - 1:
y += 1
# 第一列
elif y == 0:
x += 1
# 左下方向
else:
x += 1
y -= 1
return ans

参考资料

  • 【题解】​​「498. 对角线遍历」最简单易懂! - 对角线遍历 - 力扣(LeetCode)​​


举报

相关推荐

0 条评论