从零开始的力扣(第十六天)~
1.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
进阶:
如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。
—————————————————————————————————————————
二次循环,将每一个nums元素为首的和大于s的情况写入ans,判断ans内最小元素,但是时间复杂度为O(n2),超时不通过
class Solution(object):
def minSubArrayLen(self, s, nums):
"""
:type s: int
:type nums: List[int]
:rtype: int
"""
if not nums or sum(nums) < s:
return 0
if max(nums) >= s:
return 1
ans = []
for i in range(len(nums)):
add = 0
for j in range(i, len(nums)):
add += nums[j]
if add >= s:
ans.append(j - i + 1)
break
else:
continue
return min(ans)
双指针写法,左右指针总能找到每一部分的最小子长度,时间复杂度O(n)
class Solution(object):
def minSubArrayLen(self, s, nums):
"""
:type s: int
:type nums: List[int]
:rtype: int
"""
if s > sum(nums):
return 0
left, right, res, sum_lr = 0, 0, len(nums)+1, 0 # 双指针都从第一位出发
while right < len(nums):
while sum_lr<s and right<len(nums): # sum_lr小则右指针右移
sum_lr += nums[right]
right += 1
while sum_lr>=s and left>=0: # sum_lr大则左指针右移
res = min(res, right-left)
sum_lr -= nums[left]
left += 1
return res
二分法查找,时间复杂度O(nlogn)
class Solution(object):
def minSubArrayLen(self, s, nums):
"""
:type s: int
:type nums: List[int]
:rtype: int
"""
left, right, res = 0, len(nums), 0
def helper(size):
sum_size = 0
for i in range(len(nums)):
sum_size += nums[i]
if i >= size:
sum_size -= nums[i-size]
if sum_size >= s:
return True
return False
while left<=right:
mid = (left+right)//2 # 滑动窗口大小
if helper(mid): # 如果这个大小的窗口可以那么就缩小
res = mid
right = mid-1
else: # 否则就增大窗口
left = mid+1
return res
2.杨辉三角 II
给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例:
输入: 3
输出: [1,3,3,1]
进阶:
你可以优化你的算法到 O(k) 空间复杂度吗?
—————————————————————————————————————————
像杨辉三角(118)一样写阶乘函数,区别是这个只要求输出一行
class Solution(object):
def getRow(self, rowIndex):
"""
:type rowIndex: int
:rtype: List[int]
"""
def fractial(x):
if x in [0, 1]:
return 1
else:
return x * fractial(x - 1)
ans = [1] * (rowIndex + 1)
for i in range(1,rowIndex):
ans[i] = fractial(rowIndex)/fractial(rowIndex - i)/fractial(i)
return ans
将每一行结果保存,递推下一行
class Solution(object):
def getRow(self, rowIndex):
"""
:type rowIndex: int
:rtype: List[int]
"""
ans = []
for i in range(rowIndex + 1):
now = [1] * (i + 1)
if i >= 2:
for n in range(1, i):
now[n] = last[n] + last[n - 1]
last = now
ans += [now]
return ans.pop()
3.翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
进阶:
请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。
—————————————————————————————————————————
使用split函数用空格划分字符串,得到一个数组取反后再取字符串
class Solution(object):
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
return ''.join(str(substr + ' ') for substr in s.split()[::-1]).strip()
4.反转字符串中的单词 III
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入: “Let’s take LeetCode contest”
输出: “s’teL ekat edoCteeL tsetnoc”
注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
—————————————————————————————————————————
与上题一样,这次是翻转每个split的结果
class Solution(object):
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
return ''.join(substr[::-1] + ' ' for substr in s.split()).strip()
以上就是今日经验!