【Leetcode】解题报告Day3~Day4
解题报告
Day3
1. 66. 加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0]
输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
初次解
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
num = 0
for i in range(len(digits)):
num += digits[i]*pow(10, len(digits)-i-1)
digits = []
for n in list(str(num+1)):
digits.append(int(n))
return digits
思路
先算成数字,+1之后再变成列表
结果
其他题解
官方解
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
n = len(digits)
for i in range(n - 1, -1, -1):
if digits[i] != 9:
digits[i] += 1
for j in range(i + 1, n):
digits[j] = 0
return digits
# digits 中所有的元素均为 9
return [1] + [0] * n
从最后一位开始判断是否为9,在第一个不是9的位置+1,后续置零
2. 724. 寻找数组的中心下标
给你一个整数数组 nums
,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0
,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1
。
示例 1:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
示例 2:
输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心下标。
示例 3:
输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。
提示:
1 <= nums.length <= 104
-1000 <= nums[i] <= 1000
初次解
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
m = -1
left = 0
right = sum(nums)-nums[0]
for i in range(len(nums)):
if i > 0:
left += nums[i-1]
right -= nums[i]
if left == right:
m = i
break
return m
思路
先算好初始左右和,之后遍历数组除第一轮外每次左边加上上一位,右边减去当前位,在第一次相同的地方就停止运行
结果
其他题解
官方解
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
total = sum(nums)
left = 0
for i in range(len(nums)):
if 2 * left + nums[i] == total:
return i
left += nums[i]
return -1
反省
- 记数组的全部元素之和为 total,当遍历到第 i 个元素时,设其左侧元素之和为 sum,则其右侧元素之和为 total − nums[i] − sum。左右侧元素相等即为 sum = total − nums[i] − sum即 2 × sum + nums[i] = total
3. 189. 轮转数组
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
进阶:
- 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
- 你可以使用空间复杂度为
O(1)
的 原地 算法解决这个问题吗?
初次解
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
tmp = nums[:]
k = k % len(nums)
for i in range(len(nums)):
if k + i >= len(nums):
nums[k+i-len(nums)] = tmp[i]
else:
nums[k+i] = tmp[i]
思路
先找一个中间数组把原数组赋值过去,之后如果当前坐标加上轮转数不超出坐标的话直接轮转,超出的话就减去长度放在前边
结果
其他题解
官方解
# 方法一:使用额外的数组
# 这个方法中如果需要python在原地修改nums则需要再次遍历数组赋值
# 简单使用nums = newList是会相当于创建一个新的变量
# 方法二:环状替换
# 是真没看懂啊
# 方法三:数组翻转
# 先反转数组 再以k%n为点,前边和后边各自反转
class Solution:
def reverse(self, nums:List[int], start:int, end:int) -> None:
while(start < end):
temp = nums[start]
nums[start] = nums[end]
nums[end] = temp
start += 1
end -= 1
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= len(nums)
self.reverse(nums, 0, n-1)
self.reverse(nums, 0, k-1)
self.reverse(nums, k, n-1)
网友分享
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
k %= len(nums)
nums[:] = nums[-k:] + nums[:-k]
作者:ZXC
链接:https://leetcode.cn/problems/rotate-array/solutions/2396656/liang-xing-jie-jue-by-zxc-o-3qw5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
反省
- 对于原地修改的概念比较模糊,如果直接整个数组赋值过去会改变内存ID所以不符合要求
- 环状替换没看懂
Day4
1. 48. 旋转图像
中等
相关标签
相关企业
给定一个 n × n 的二维矩阵 matrix
表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
提示:
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
初次解
没想出来
其他题解
官方
# 方法一:使用辅助数组
# 因为第i行都会变成第-(i+1)列
# 所以创建一个空数组来辅助旋转
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
n = len(matrix)
# Python 这里不能 matrix_new = matrix 或 matrix_new = matrix[:] 因为是引用拷贝
matrix_new = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
matrix_new[j][n - i - 1] = matrix[i][j]
# 不能写成 matrix = matrix_new
matrix[:] = matrix_new
# 方法二:原地旋转
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
n = len(matrix)
for i in range(n // 2):
for j in range((n + 1) // 2):
matrix[i][j], matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1] \
= matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1], matrix[i][j]
# 方法三:用翻转代替旋转
class Solution:
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]
2. 54. 螺旋矩阵
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
官方解
方法1
从左上开始,当路径超出界限或者之前访问过则顺时针旋转进入下一个方向
是否访问过使用辅助矩阵判断
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return list()
rows, columns = len(matrix), len(matrix[0])
# 设置初始全为False的辅助检验矩阵
visited = [[False] * columns for _ in range(rows)]
total = rows * columns
order = [0] * total
# 一共有四个方向
# 列+1为向右 行+1为向下 列-1为向左 行-1为向上
# 初始为向右
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
row, column = 0, 0
# 每次变向+1且%4控制变向
directionIndex = 0
for i in range(total):
order[i] = matrix[row][column]
# 标记已访问
visited[row][column] = True
nextRow, nextColumn = row + directions[directionIndex][0], column + directions[directionIndex][1]
# 判断是否出界或已访问
if not (0 <= nextRow < rows and 0 <= nextColumn < columns and not visited[nextRow][nextColumn]):
directionIndex = (directionIndex + 1) % 4
row += directions[directionIndex][0]
column += directions[directionIndex][1]
return order
方法2
把矩阵看成分层的
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return list()
rows, columns = len(matrix), len(matrix[0])
order = list()
# 初始定位四个角
left, right, top, bottom = 0, columns - 1, 0, rows - 1
while left <= right and top <= bottom:
for column in range(left, right + 1):
order.append(matrix[top][column])
for row in range(top + 1, bottom + 1):
order.append(matrix[row][right])
if left < right and top < bottom:
for column in range(right - 1, left, -1):
order.append(matrix[bottom][column])
for row in range(bottom, top, -1):
order.append(matrix[row][left])
# 缩小到第二层
left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1
return order
3. 498. 对角线遍历
给你一个大小为 m x n
的矩阵 mat
,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
示例 1:
输入:mat = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,4,7,5,3,6,8,9]
示例 2:
输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 104
1 <= m * n <= 104
-105 <= mat[i][j] <= 105
其他题解
- 右斜对角线是横纵坐标和为定值(左斜的话是差为定值)。
- 一共有m+n−1个对角线,对应左上角贴边走到右下角
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
m, n, ans = len(mat), len(mat[0]), []
for k in range(m + n - 1):
if not k % 2:
ans += [mat[x][k-x] for x in range(min(m - 1, k), max(-1, k - n),-1)]
else:
ans += [mat[x][k-x] for x in range(max(0, k - n + 1), min(k + 1, m))]
return ans
作者:Benhao
链接:https://leetcode.cn/problems/diagonal-traverse/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
反省
day4的是一题没做出来啊
感觉自己这种数学的坐标推算还是比较薄弱,在把这几题多做几遍