455.分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例 1:

1
2
3
4
5
6
输入: g = [1,2,3], s = [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

示例 2:

1
2
3
4
5
6
输入: g = [1,2], s = [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

思路:

对小孩胃口和饼干进行排序

遍历饼干 相当于拿饼干一个个尝试喂

如果小孩人数还没有喂完 并且能满足胃口 那么跳到下个小孩

代码:

1
2
3
4
5
6
7
8
9
10
class Solution:
# 思路1:优先考虑小胃口
def findContentChildren(self, g, s) :
g.sort() # 表示胃口
s.sort() # 表示饼干大小
res = 0# res绑定的是小孩的胃口坐标
for i in range(len(s)):
if res <len(g) and s[i] >= g[res]: #小饼干先喂饱小胃口
res += 1
return res

376.摆动序列

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。

  • 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。
  • 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。

给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。

示例 1:

1
2
3
输入:nums = [1,7,4,9,2,5]
输出:6
解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。

示例 2:

1
2
3
4
输入:nums = [1,17,5,10,13,15,10,5,16,8]
输出:7
解释:这个序列包含几个长度为 7 摆动序列。
其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。

示例 3:

1
2
输入:nums = [1,2,3,4,5,6,7,8,9]
输出:2

思路:

三个参数分别用来记录 自己和左边的差值 自己和右边的差值 摆动长度

代码:

1
2
3
4
5
6
7
8
9
class Solution:
def wiggleMaxLength(self, nums) -> int:
preC,curC,res = 0,0,1 #题目里nums长度大于等于1,当长度为1时,其实到不了for循环里去,所以不用考虑nums长度
for i in range(len(nums) - 1):# 由于要统计自己后面的元素 遍历-1
curC = nums[i + 1] - nums[i]# 当前差值
if curC * preC <= 0 and curC !=0: # 差值为0时,不算摆动 prec为0 curc为0也算摆动
res += 1
preC = curC #如果当前差值和上一个差值为一正一负时,才需要用当前差值替代上一个差值
return res

53.最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

1
2
3
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

1
2
输入:nums = [1]
输出:1

示例 3:

1
2
输入:nums = [5,4,-1,7,8]
输出:23

思路:

求全局最大子序列 换算到局部

比如定位到一个正数 只要左边的序列和为正 加上左边就是有益 就可以判断是否超过了max

如果左边的序列和为负 加上左边就会无益 需要重新开始

代码

1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
def maxSubArray( nums) -> int:
result = -float('inf') # 定义记录为负无穷
count = 0 # 记录局部序列和
for i in range(len(nums)):
count += nums[i]
if count > result:
result = count # 这边记录的是连续序列的最大result
if count <= 0:
count = 0 # 开始新的序列计数
return result

122.买卖股票的最佳时机 II

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

示例 1:

1
2
3
4
5
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。

示例 2:

1
2
3
4
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
总利润为 4 。

示例 3:

1
2
3
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。

思路:

只要明天减今天为正 那么result就要加上

如果为负 那么result就要加0

1
2
3
4
5
6
7
8
9
# 比如第四天的售卖价格减去第一天的售卖价格 也就是这三天的利润等于第二天-第一天的利润加上第三天减第二天的利润加第四天减第三天的利润
# 统计每天的利润 只要利润为正就是时机

class Solution:
def maxProfit(self, prices):
result = 0
for i in range(1, len(prices)):
result += max(prices[i] - prices[i - 1], 0)
return result

55.跳跃游戏

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例 1:

1
2
3
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

1
2
3
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

代码:

1
2
3
4
5
6
7
8
9
10
class Solution:
def canJump(self, nums):
cover = 0 # 从0位置开始
if len(nums) == 1: return True # 如果数组长度本身就为1 就立即返回true
for i in range(len(nums)): # 遍历整个跳跃数组
if i <= cover: # 等于cover的时候覆盖末尾 此时i<cover如果满足的话表明 i这个位置可以到达
cover = max(i + nums[i], cover)
if cover >= len(nums) - 1:
return True
return False

45.跳跃游戏 II

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。

示例 1:

1
2
3
4
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

1
2
输入: nums = [2,3,0,1,4]
输出: 2

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 统计到达终点的最短步数
class Solution:
def jump(nums):
if len(nums) == 1: return # 如果长度为1 不用跳就已经到达终点
ans = 0
curDistance = 0 # 用来统计每一阶段的末尾
nextDistance = 0 #下一眺的覆盖范围
for i in range(len(nums)):
nextDistance = max(i + nums[i], nextDistance)
if i == curDistance:# i走到覆盖范围的末尾
if curDistance != len(nums) - 1:# 还没有到最终的末尾时
ans += 1
curDistance = nextDistance
if nextDistance >= len(nums) - 1:
break
return ans

1005.K 次取反后最大化的数组和

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组 可能的最大和 。

示例 1:

1
2
3
输入:nums = [4,2,3], k = 1
输出:5
解释:选择下标 1 ,nums 变为 [4,-2,3] 。

示例 2:

1
2
3
输入:nums = [3,-1,0,2], k = 3
输出:6
解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。

示例 3:

1
2
3
输入:nums = [2,-3,-1,5,-4], k = 2
输出:13
解释:选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。

代码:

1
2
3
4
5
6
7
8
9
10
class Solution:
def largestSumAfterKNegations(A, K):
A = sorted(A, key=abs, reverse=True) # 将A按绝对值从大到小排列
for i in range(len(A)):# 遍历从大到小的绝对值数组A
if K > 0 and A[i] < 0:
A[i] *= -1
K -= 1
if K > 0:
A[-1] *= (-1)**K #取A最后一个数只需要写-1
return sum(A)

134.加油站

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

示例 1:

1
2
3
4
5
6
7
8
9
10
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。

示例 2:

1
2
3
4
5
6
7
8
9
输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 解法2
class Solution:
def canCompleteCircuit(self, gas, cost):
start = 0
curSum = 0 # 记录当前加油站到下一个加油站消耗的盈余
totalSum = 0 # 用来记录总的耗油量
for i in range(len(gas)):# 遍历所有的加油站
curSum += gas[i] - cost[i]
totalSum += gas[i] - cost[i]
if curSum < 0: # 如果剩余油量为负数 则跑不到该加油站
curSum = 0 # 重新计数为下一个加油站
start = i + 1
if totalSum < 0: return -1# 总的油量不够消耗的油量 则 不可能跑完全局
return start

135.分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

1
2
3
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

示例 2:

1
2
3
4
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

代码:

1
2
3
4
5
6
7
8
9
10
class Solution:
def candy(self, ratings):
candyVec = [1] * len(ratings)# 首先确定的是每个孩子都分发到一个糖果
for i in range(1, len(ratings)):# 从左向右遍历 右边的孩子比左边的评分高 右边的孩子糖果加一
if ratings[i] > ratings[i - 1]:
candyVec[i] = candyVec[i - 1] + 1
for j in range(len(ratings) - 2, -1, -1):# 从右向左遍历
if ratings[j] > ratings[j + 1]:# 左边的孩子比右边的孩子评分高 取max
candyVec[j] = max(candyVec[j], candyVec[j + 1] + 1)
return sum(candyVec)

860.柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

示例 1:

1
2
3
4
5
6
7
输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。

示例 2:

1
2
3
4
5
6
7
输入:bills = [5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def lemonadeChange(self, bills) -> bool:
five, ten = 0, 0 # 统计五元和十元的数量
for bill in bills:
if bill == 5:# 顾客给的是五元
five += 1
elif bill == 10:# 顾客给的是十元
if five < 1: return False
five -= 1
ten += 1
else: # 顾客给的是二十元
if ten > 0 and five > 0:
ten -= 1
five -= 1
elif five > 2:
five -= 3
else:
return False
return True

406.根据身高重建队列

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

示例 1:

1
2
3
4
5
6
7
8
9
10
输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解释:
编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。

示例 2:

1
2
输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def reconstructQueue( people):
# 先按照h维度的身高顺序从高到低排序。确定第一个维度
# lambda返回的是一个元组:当-x[0](维度h)相同时,再根据x[1](维度k)从小到大排序
# 第一维度从大到小排序 第二维度 从小到大排序
people.sort(key=lambda x: (-x[0], x[1]))
que = []

# 根据每个元素的第二个维度k,贪心算法,进行插入
# people已经排序过了:同一高度时k值小的排前面。
for p in people:
que.insert(p[1], p)
return que

452.用最少数量的箭引爆气球

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start,x``end, 且满足 xstart ≤ x ≤ x``end,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

示例 1:

1
2
3
4
5
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。

示例 2:

1
2
3
输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。

示例 3:

1
2
3
4
5
输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:气球可以用2支箭来爆破:
- 在x = 2处发射箭,击破气球[1,2]和[2,3]。
- 在x = 4处射出箭,击破气球[3,4]和[4,5]。

代码:

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def findMinArrowShots( points) -> int:
if len(points) == 0: return 0
points.sort(key=lambda x: x[0])
result = 1
for i in range(1, len(points)):
if points[i][0] > points[i - 1][1]: # 气球i的起点位置 大于 气球i+1的终点位置 表明两个气球不重叠
result += 1
else:# 两个气球有重叠
points[i][1] = min(points[i - 1][1], points[i][1]) # 更新重叠气球最小右边界
return result

435.无重叠区间

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。

示例 1:

1
2
3
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

1
2
3
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

1
2
3
输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

代码:

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def eraseOverlapIntervals( intervals):
if len(intervals) == 0: return 0
intervals.sort(key=lambda x: x[1])
count = 1 # 记录非交叉区间的个数 也就是连续的个数 统计连续的个数顺便把不连续的也就求得出来
end = intervals[0][1] # 记录区间分割点
for i in range(1, len(intervals)):
if end <= intervals[i][0]:
count += 1
end = intervals[i][1]
return len(intervals) - count

763.划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

示例 1:

1
2
3
4
5
6
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。

示例 2:

1
2
输入:s = "eccbbbbdec"
输出:[10]

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 同一字母在一个片段中
class Solution:
def partitionLabels(s):
hash = [0] * 26 # 统计字母出现的最远位置
for i in range(len(s)):
hash[ord(s[i]) - ord('a')] = i
result = []
left = 0
right = 0
for i in range(len(s)):
# 在区间的字母中出现的最远位置 比如ababcbaca 出现了三个字母 这三个字母出现的最远位置为8
right = max(right, hash[ord(s[i]) - ord('a')])

if i == right:
result.append(right - left + 1)
left = i + 1
return result

56.合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

1
2
3
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

1
2
3
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def merge(intervals):
if len(intervals) == 0: return intervals
intervals.sort(key=lambda x: x[0]) # 对区间进行起始位置排序
result = []
result.append(intervals[0])
for i in range(1, len(intervals)): # 遍历所有区间
last = result[-1]
if last[1] >= intervals[i][0]:# 统计最后一个区间终点位置大于选中区间起始位置
result[-1] = [last[0], max(last[1], intervals[i][1])] # 区间合并
else:
result.append(intervals[i])
return result

738.单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

示例 1:

1
2
输入: n = 10
输出: 9

示例 2:

1
2
输入: n = 1234
输出: 1234

示例 3:

1
2
输入: n = 332
输出: 299

代码:

1
2
3
4
5
6
7
8
class Solution:
def monotoneIncreasingDigits(n: int) -> int:
a = list(str(n))
for i in range(len(a)-1,0,-1):
if int(a[i]) < int(a[i-1]): # 当后一个数比前一个数小时
a[i-1] = str(int(a[i-1]) - 1) # 修改前一个数-1
a[i:] = '9' * (len(a) - i) # 剩余的数全部赋值9
return int("".join(a))