【LeetCode刷题】第一期
一:1248.统计[优美子数组](中等)
题目描述:传送门
法一:暴力求解
思路:把所有子数组列出来,再遍历一遍,看其中满足条件的有几个
def is_odd(n):
return 1 if n%2 == 1 else 0
def odd_num(array):
count = 0
for i in array:
if is_odd(i):
count += 1
return count
class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
children = []
count = 0
# 求出所有子数组
for i in range(len(nums)):
for j in range(i, len(nums)):
children.append(nums[i:j+1])
# print(children)
for i in range(len(children)):
if odd_num(children[i]) == k:
count += 1
return count
时间复杂度:O(n^2)
当然,这种做法会超出时间限制。
法二:数学
解析可参考leetcode上,这里需要说明的是,之所以要在odds开头和结尾加一个-1和原数组长,就是为了处理边界的情况。
- 假设第一个奇数是i,那么对应的优美子数组的左侧就应该有i+1种情况。比如[2,4,1,1,3,4,5,6,7,3,2],第一个奇数的下标是2,但是第一个奇数为原数组中第三个1的优美子数组的左侧有[1],[4,1].[2,4,1]三种情况,所以2+1才是正解
- 假设最后一个不是奇数,那么也要考虑最后一个奇数到原数组最后一个位置有n-最后一个奇数下标种情况
class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
ans = 0 # 最终的结果
odds = [-1] # 存放所有奇数的下标,这里先存放一个-1,这样后面的数减去它的时候就相当于+1
for index, num in enumerate(nums):
if num % 2 == 1:
odds.append(index)
odds.append(len(nums)) # 存放一个总长度
for i in range(1, len(odds)-k):
ans += (odds[i] - odds[i-1])*(odds[i+k] - odds[i+k-1])
return ans
时间复杂度:O(n)
空间复杂度:O(n)
法三:前缀和
待做
二:26.删除排序数组中的重复项(简单)
思路:双指针。因为输出是原数组里的不重复数字的个数,且原数组已排序。所以只需要两个指针,一个负责记录以及去重,一个负责往后遍历。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
i = 0
for j in range(1, len(nums)):
if nums[i] != nums[j]:
i += 1
nums[i] = nums[j]
return i+1
三:1672.最富有客户的资产总量(简单)
class Solution:
def maximumWealth(self, accounts: List[List[int]]) -> int:
ans = 0
for i in range(len(accounts)):
temp = sum(accounts[i])
if temp > ans:
ans = temp
return ans
题目很简单,for循环里面嵌套sum求和,复杂度挺高的。
四:1480.一维数组的动态和(简单)
class Solution:
def runningSum(self, nums: List[int]) -> List[int]:
ans = [nums[0]]
for i in range(1, len(nums)):
ans.append(ans[i-1] + nums[i])
return ans
优化:直接在原数组上进行操作:
class Solution:
def runningSum(self, nums: List[int]) -> List[int]:
for i in range(1, len(nums)):
nums[i] += nums[i-1]
return nums
五:1512.好数对的数目
1.暴力解法
class Solution:
def numIdenticalPairs(self, nums: List[int]) -> int:
count = 0
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[j] == nums[i]:
count += 1
return count
2.优化
思路:在整个数组中,我们只需要知道每一个数对应的个数,然后相当于在k个相同的数中任意取两个,就是
C
k
2
C_{k}^2
Ck2。所以第一步优化可以先使用字典统计每一个数出现的个数,之后使用公式计算。
但是,由于
C
k
2
=
k
(
k
−
1
)
2
=
1
+
2
+
3
+
⋅
⋅
⋅
+
(
k
−
1
)
C_{k}^2=\frac{k(k-1)}{2}=1+2+3+···+(k-1)
Ck2=2k(k−1)=1+2+3+⋅⋅⋅+(k−1)
一个数第一次出现:
C
1
2
=
0
C_{1}^2=0
C12=0
第二次出现,
C
2
2
=
1
C_{2}^2=1
C22=1
第三次出现,
C
3
2
=
3
C_{3}^2=3
C32=3
第四次出现,
C
4
2
=
6
C_{4}^2=6
C42=6
第五次出现,
C
5
2
=
10
C_{5}^2=10
C52=10
发现没有,第一次是0,第二次是0+1,第三次是0+1+2,第四次是0+1+2+3,第五次是0+1+2+3+4。以此类推。这样一来,我们可以建立一个全0数组,依次遍历,给计数的count加上该数对应位置数字的统计数,然后,在该数对应的位置加1(类似字典),以便下次加在统计数上。
class Solution:
def numIdenticalPairs(self, nums: List[int]) -> int:
count = 0
temp = [0] * 100
for i in nums:
count += temp[i-1]
temp[i-1] += 1
return count