【LeetCode数组相关】中心下标、旋转图像、零矩阵
LeetCode724.寻找数组的中心下标
给你一个整数数组 nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
示例 1:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3(我认为这里是6才对)
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
最开始的思路:
1、将原始的数组翻转得到一个新数组,然后同时遍历两个数组,当相加结果相同时返回当前下标对应的数
问题:
显然,这种方法只适用于对称的数组,是特例
2、朴素的思想是双层for循环去遍历数组,相加之后比较得出结果
问题:
因为需要确认边界,所以慢,容易超时
解题思路:
使用前缀法
有这样的规律,
记数组全部元素之和为numSum,当遍历到第i个元素时,其左侧元素总和为leftSum,右侧则可以表示为全部元素之和减掉左侧元素之和再减掉当前第i个元素,即
rightSum = numSum - leftSum - nums[i]
如果左右元素之和相等则找到中心下标
代码实现:
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
numSum = sum(nums) #求数组总和
leftSum = 0
for i in range(len(nums)):
# 前缀法
if numSum - leftSum - nums[i] == leftSum:
#左右和相等,则返回当前下标
return i
#左侧总和累加
leftSum += nums[i]
return -1
LeetCode48.旋转图像
给你一幅由 N × N
矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 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]
]
解题思路:
需要找规律,如果用暴力法。确定每个数变化后的位置再一个一个修改,算法复杂度会比较高
翻转法是本题一个比较好的结题思路
先将目标矩阵镜像翻转
[
[1,2,3],
[4,5,6],
[7,8,9]
]
镜像↓
[
[3,2,1],
[6,5,4],
[9,8,7]
]
再沿主对角线对折即可
[
[3,2,1],
[6,5,4],
[9,8,7]
]
主对角线翻转↓
[
[3,6,9],
[2,5,8],
[1,4,7]
]
图像向左旋转了90°
如果是先主对角线翻转再镜像翻转的话,图像会向右旋转90°
因为题目没有规定方向,所以两种都可以
代码:
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
# 确定matrix长度
m1= len(matrix)
# 先用切片操作镜像翻转matrix
# matrix[:]等于复制了一个一样的matrix
# matrix[::-1]相当于将对象镜像翻转
matrix[:] = matrix[::-1] #得到镜像翻转后的matrix
# 沿主对角线翻转
# 注意len不是从0开始的
for i in range(m1):
for j in range(i):
matrix[j][i], matrix[i][j] = matrix[i][j], matrix[j][i]
ps:这里有个python的小技巧--切片操作
例如,
a = 'saiodhoia'
b = a[:]
c = a[::-1]
print(b)
-->saiodhoia
print(c)
-->aiohdoias
# 上述操作对list依然有效
LeetCode73.零矩阵
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
解题思路:
很容易想到用遍历的方式去做。遇到0怎么处理是关键
一种朴素的解法是使用两次遍历
第一次遍历确定0的位置并保存下来,第二次根据第一次保存的位置信息修改矩阵中的值
代码:
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
# 获取内外层数组长度
m1, m2 = len(matrix), len(matrix[0])
# 定义两个数组用于存放位置信息,1表示在原数组中该位置不为0
row, column = [1]*m1, [1]*m2
# 第一遍遍历,定位出0的位置
for i in range(m1):
for j in range(m2):
if matrix[i][j] == 0:
# 找到0就标记一下
row[i] = 0
column[j] = 0
# 第二遍遍历,按照位置信息修改矩阵
for i in range(m1):
for j in range(m2):
if row[i] == 0 or column[j] == 0:
matrix[i][j] = 0
还有更优解,之后有空再优化