目录
1476. 子矩形查询
https://leetcode-cn.com/problems/subrectangle-queries/
请你实现一个类 SubrectangleQueries ,它的构造函数的参数是一个 rows x cols 的矩形(这里用整数矩阵表示),并支持以下两种操作:
1. updateSubrectangle(int row1, int col1, int row2, int col2, int newValue),用 newValue 更新以 (row1,col1) 为左上角且以 (row2,col2) 为右下角的子矩形。
2. getValue(int row, int col),返回矩形中坐标 (row,col) 的当前值。
示例 1:
输入:
["SubrectangleQueries","getValue","updateSubrectangle","getValue","getValue","updateSubrectangle","getValue","getValue"]
[[[[1,2,1],[4,3,4],[3,2,1],[1,1,1]]],[0,2],[0,0,3,2,5],[0,2],[3,1],[3,0,3,2,10],[3,1],[0,2]]
输出:
[null,1,null,5,5,null,10,5]
解释:
SubrectangleQueries subrectangleQueries = new SubrectangleQueries([[1,2,1],[4,3,4],[3,2,1],[1,1,1]]);
// 初始的 (4x3) 矩形如下:
// 1 2 1
// 4 3 4
// 3 2 1
// 1 1 1
subrectangleQueries.getValue(0, 2); // 返回 1
subrectangleQueries.updateSubrectangle(0, 0, 3, 2, 5);
// 此次更新后矩形变为:
// 5 5 5
// 5 5 5
// 5 5 5
// 5 5 5
subrectangleQueries.getValue(0, 2); // 返回 5
subrectangleQueries.getValue(3, 1); // 返回 5
subrectangleQueries.updateSubrectangle(3, 0, 3, 2, 10);
// 此次更新后矩形变为:
// 5 5 5
// 5 5 5
// 5 5 5
// 10 10 10
subrectangleQueries.getValue(3, 1); // 返回 10
subrectangleQueries.getValue(0, 2); // 返回 5
示例 2:
输入:
["SubrectangleQueries","getValue","updateSubrectangle","getValue","getValue","updateSubrectangle","getValue"]
[[[[1,1,1],[2,2,2],[3,3,3]]],[0,0],[0,0,2,2,100],[0,0],[2,2],[1,1,2,2,20],[2,2]]
输出:
[null,1,null,100,100,null,20]
解释:
SubrectangleQueries subrectangleQueries = new SubrectangleQueries([[1,1,1],[2,2,2],[3,3,3]]);
subrectangleQueries.getValue(0, 0); // 返回 1
subrectangleQueries.updateSubrectangle(0, 0, 2, 2, 100);
subrectangleQueries.getValue(0, 0); // 返回 100
subrectangleQueries.getValue(2, 2); // 返回 100
subrectangleQueries.updateSubrectangle(1, 1, 2, 2, 20);
subrectangleQueries.getValue(2, 2); // 返回 20
提示:
最多有 500 次updateSubrectangle 和 getValue 操作。
1 <= rows, cols <= 100
rows == rectangle.length
cols == rectangle[i].length
0 <= row1 <= row2 < rows
0 <= col1 <= col2 < cols
1 <= newValue, rectangle[i][j] <= 10^9
0 <= row < rows
0 <= col < cols
题解
一:矩阵规模和操作次数不算很大,可以直接操作。
二:空间换时间,思路挺赞的,下面转一下大神题解,https://leetcode-cn.com/problems/subrectangle-queries/solution/bu-bao-li-geng-xin-ju-zhen-yuan-su-de-jie-fa-by-li/,
这道题暴力模拟就可以通过,不多说了。但是,这个问题可以不暴力更新矩阵的内容。
我们可以设置一个history的数组,记录每次调用updateSubrectangle的信息。这样,updateSubrectangle的复杂度是 O(1) 的。
相应的,在 getValue 的过程中,我们只需要倒序查找我们记录的 history,如果发现我们要查找的 (row, col) 包含在某一次历史更新的位置中,直接返回这个历史更新值就好了。否则的,历史更新没有动过这个位置,返回原始矩阵中这个位置的值。
class SubrectangleQueries(object):
def __init__(self, rectangle):
"""
:type rectangle: List[List[int]]
"""
m, n = len(rectangle), len(rectangle[0])
self.rectangle = [[rectangle[i][j] for j in range(n)] for i in range(m)]
self.history = []
def updateSubrectangle(self, row1, col1, row2, col2, newValue):
"""
:type row1: int
:type col1: int
:type row2: int
:type col2: int
:type newValue: int
:rtype: None
"""
self.history.append([row1, col1, row2, col2, newValue])
def getValue(self, row, col):
"""
:type row: int
:type col: int
:rtype: int
"""
n = len(self.history)
for i in range(n - 1, -1, -1):
if (self.history[i][0] <= row <= self.history[i][2] and self.history[i][1] <= col <= self.history[i][3]):
return self.history[i][4]
return self.rectangle[row][col]
# Your SubrectangleQueries object will be instantiated and called as such:
# obj = SubrectangleQueries(rectangle)
# obj.updateSubrectangle(row1,col1,row2,col2,newValue)
# param_2 = obj.getValue(row,col)
1475. 商品折扣后的最终价格
https://leetcode-cn.com/problems/final-prices-with-a-special-discount-in-a-shop/
给你一个数组 prices ,其中 prices[i] 是商店里第 i 件商品的价格。商店里正在进行促销活动,如果你要买第 i 件商品,那么你可以得到与 prices[j] 相等的折扣,其中 j 是满足 j > i 且 prices[j] <= prices[i] 的 最小下标 ,如果没有满足条件的 j ,你将没有任何折扣。请你返回一个数组,数组中第 i 个元素是折扣后你购买商品 i 最终需要支付的价格。
示例 1:输入:prices = [8,4,6,2,3],输出:[4,2,4,2,3]
解释:
商品 0 的价格为 price[0]=8 ,你将得到 prices[1]=4 的折扣,所以最终价格为 8 - 4 = 4 。
商品 1 的价格为 price[1]=4 ,你将得到 prices[3]=2 的折扣,所以最终价格为 4 - 2 = 2 。
商品 2 的价格为 price[2]=6 ,你将得到 prices[3]=2 的折扣,所以最终价格为 6 - 2 = 4 。
商品 3 和 4 都没有折扣。
示例 2:输入:prices = [1,2,3,4,5],输出:[1,2,3,4,5],解释:在这个例子中,所有商品都没有折扣。
示例 3:输入:prices = [10,1,1,6],输出:[9,0,1,6]
提示:1 <= prices.length <= 500,1 <= prices[i] <= 10^3
题解
一:暴力解法,时间复杂度O(n^2)。
class Solution(object):
def finalPrices(self, prices):
"""
:type prices: List[int]
:rtype: List[int]
"""
ans, n = prices[:], len(prices)
min_val = prices[-1]
for i in range(n -2, -1, -1):
if prices[i] < min_val:
min_val = prices[i]
else:
for j in range(i + 1, n):
if prices[j] <= prices[i]:
ans[i] = prices[i] - prices[j]
break
return ans
二:单调递增栈,时间复杂度O(n),时间复杂度O(n),新的元素肯定是要入栈的,并且必须维持单调递增栈的性质。若新元素比栈顶元素大则直接入栈成为栈顶,若小于等于栈顶元素,所有比新元素大的元素全部出栈(由于单调递增栈,只要栈顶元素小于新元素则栈内元素必小于新元素)。这边说说为啥可以用单调递增栈,因为这边需要减去第一个小于等于该元素的元素的值,当新元素值大于栈顶元素,则栈内的所有元素都没有找到比他小的元素,无需处理;若新元素小于等于栈顶元素,则对于栈内所有比它大的元素来说,新元素都是小于该元素的第一个值,此刻处理。参考大神题解,https://leetcode-cn.com/problems/final-prices-with-a-special-discount-in-a-shop/solution/dan-diao-zhan-zui-quan-mian-xiang-jie-bao-ni-dong-/,https://leetcode-cn.com/problems/final-prices-with-a-special-discount-in-a-shop/solution/dan-diao-zhan-ji-chu-ti-kan-bu-dong-da-lou-shang-b/,以及可以看看大神的博客,https://mp.weixin.qq.com/s/poOH6CbXKtdGf1raBBI-0g,关于单调栈算法的讲解,文中写的还是清晰的。
class Solution(object):
def finalPrices(self, prices):
# 列表stack的append和pop刚好和栈的先进后出对应上。
# stack[0]栈底,stack[-1]栈顶
# 这边栈存储的是下标,其下标对应的值从栈顶到栈底递增
stack, ans, n = [], prices[:], len(prices)
for i in range(n):
while len(stack) > 0 and ans[i] <= ans[stack[-1]]:
idx = stack.pop()
ans[idx] -= ans[i]
stack.append(i)
return ans
739. 每日温度
https://leetcode-cn.com/problems/daily-temperatures/
请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
题解
一:非递增栈,参见姐妹题1475. 商品折扣后的最终价格,相似点,都要找到大于或小于等于的第一个,再处理。
class Solution(object):
def dailyTemperatures(self, T):
"""
:type T: List[int]
:rtype: List[int]
"""
n = len(T)
# 非递增栈,从栈顶stack[-1]到栈底stack[0]非递增,也即是stack当作列表看非递减排序
# stack存下标
stack, ans = [], [0] * n
for i in range(n):
while len(stack) != 0 and T[i] > T[stack[-1]]:
idx = stack.pop()
ans[idx] = i - idx
stack.append(i)
# stack栈内最终存在的下标不用处理,因为他们后面没有比它更高的了,直接用初始值0即可。
return ans
950. 按递增顺序显示卡牌
https://leetcode-cn.com/problems/reveal-cards-in-increasing-order/
牌组中的每张卡牌都对应有一个唯一的整数。你可以按你想要的顺序对这套卡片进行排序。最初,这些卡牌在牌组里是正面朝下的(即,未显示状态)。
现在,重复执行以下步骤,直到显示所有卡牌为止:
从牌组顶部抽一张牌,显示它,然后将其从牌组中移出。
如果牌组中仍有牌,则将下一张处于牌组顶部的牌放在牌组的底部。
如果仍有未显示的牌,那么返回步骤 1。否则,停止行动。
返回能以递增顺序显示卡牌的牌组顺序。
答案中的第一张牌被认为处于牌堆顶部。
示例:输入:[17,13,11,2,3,5,7],输出:[2,13,3,11,5,17,7]
解释:
我们得到的牌组顺序为 [17,13,11,2,3,5,7](这个顺序不重要),然后将其重新排序。
重新排序后,牌组以 [2,13,3,11,5,17,7] 开始,其中 2 位于牌组的顶部。
我们显示 2,然后将 13 移到底部。牌组现在是 [3,11,5,17,7,13]。
我们显示 3,并将 11 移到底部。牌组现在是 [5,17,7,13,11]。
我们显示 5,然后将 17 移到底部。牌组现在是 [7,13,11,17]。
我们显示 7,并将 13 移到底部。牌组现在是 [11,17,13]。
我们显示 11,然后将 17 移到底部。牌组现在是 [13,17]。
我们展示 13,然后将 17 移到底部。牌组现在是 [17]。
我们显示 17。
由于所有卡片都是按递增顺序排列显示的,所以答案是正确的。
提示:1 <= A.length <= 1000,1 <= A[i] <= 10^6,对于所有的 i != j,A[i] != A[j]
题解
一:通过,看了示例的无道理的感觉,总感觉是每隔一个未取到的下标取下标。
class Solution(object):
def deckRevealedIncreasing(self, deck):
"""
:type deck: List[int]
:rtype: List[int]
"""
n = len(deck)
deck = sorted(deck)
ans, count, i = [0] * n, 0, 0
while True:
i = i % n
ans[i] = deck[count]
count += 1
if count >= n:
return ans
local_count = 0
while local_count < 2:
i = (i + 1) % n
if ans[i] == 0:
local_count += 1
return ans
二:模拟法,参考各大神题解,用q来模拟操作顺序,q中存储下表,将deck排序,每次都是取最上面的,即q最左侧的下标(取出,即弹出popleft)放置目前最小的数,若还有牌(即q不为空),将下一张牌放到最底下(即将目前q的最左侧的下标弹出并放入最右端,即不为空,先popleft,再append)。
from collections import deque
class Solution(object):
def deckRevealedIncreasing(self, deck):
q = deque(range(len(deck)))
ans = deck[:]
for item in sorted(deck):
ans[q.popleft()] = item
if q:
index = q.popleft()
q.append(index)
return ans
665. 非递减数列
https://leetcode-cn.com/problems/non-decreasing-array/
给你一个长度为 n 的整数数组,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。我们是这样定义一个非递减数列的: 对于数组中所有的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。
示例 1:输入: nums = [4,2,3],输出: true
解释: 你可以通过把第一个4变成1来使得它成为一个非递减数列。
示例 2:输入: nums = [4,2,1],输出: false
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。
说明:1 <= n <= 10 ^ 4,- 10 ^ 5 <= nums[i] <= 10 ^ 5
题解
一:暴力法,O(n^2)的时间复杂度,每次修改一个值,看是否满足非递减序列。下标0的元素特殊处理,取0,1的最小值,其余的在破坏非递减序列的时候,只需要让它等于他前面的一个元素,该元素也是最有可能使后面满足非递减条件的。
class Solution(object):
def checkPossibility(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
def check(nums):
for i in range(1, len(nums)):
if nums[i] < nums[i - 1]:
return False
return True
n = len(nums)
if n <= 2:
return True
for i in range(1, n):
if check(nums[: i] + [nums[i - 1]] + nums[i + 1: ]):
return True
if check([min(nums[:2])] + [min(nums[:2])] + nums[2:]):
return True
return False
二:找出破坏了非递减的元素,O(n)时间复杂度。
class Solution(object):
def checkPossibility(self, nums):
def check(nums):
for i in range(1, len(nums)):
if nums[i] < nums[i - 1]:
return False
return True
n = len(nums)
if n <= 2:
return True
l = 1
while l < n:
if nums[l] < nums[l - 1]:
break
l += 1
if l >= n - 1:
return True
# nums[l - 1] > nums[l]
if l == 1:
if check([min(nums[:2])] + nums[2:]):
return True
return False
if nums[l] < nums[l - 2]:
if check(nums[: l] + [nums[l - 1]] + nums[l + 1:]):
return True
return False
if nums[l] >= nums[l - 2]:
if check(nums[: l - 1] + [nums[l]] + nums[l:]):
return True
return False
三:缩小问题规模,和二差不多。
class Solution(object):
def checkPossibility(self, nums):
n = len(nums)
if n <= 2:
return True
while len(nums) >= 3:
if nums[0] <= nums[1] <= nums[2]:
nums.pop(0)
else:
break
while len(nums) >= 3:
if nums[-3] <= nums[-2] <= nums[-1]:
nums.pop()
else:
break
n = len(nums)
if n <= 2:
return True
elif n == 3:
if not (nums[0] > nums[1] > nums[2]):
return True
elif n == 4:
if nums[0]>nums[1]:
return False
if nums[-1]<nums[-2]:
return False
return nums[0]<=nums[1]<=nums[3] or nums[0]<=nums[2]<=nums[3]
else:
return False
return False
1395. 统计作战单位数
https://leetcode-cn.com/problems/count-number-of-teams/
n 名士兵站成一排。每个士兵都有一个 独一无二 的评分 rating 。每 3 个士兵可以组成一个作战单位,分组规则如下:
从队伍中选出下标分别为 i、j、k 的 3 名士兵,他们的评分分别为 rating[i]、rating[j]、rating[k]
作战单位需满足: rating[i] < rating[j] < rating[k] 或者 rating[i] > rating[j] > rating[k] ,其中 0 <= i < j < k < n
请你返回按上述条件可以组建的作战单位数量。每个士兵都可以是多个作战单位的一部分。
示例 1:输入:rating = [2,5,3,4,1]、输出:3
解释:我们可以组建三个作战单位 (2,3,4)、(5,4,1)、(5,3,1) 。
示例 2:输入:rating = [2,1,3]、输出:0
解释:根据题目条件,我们无法组建作战单位。
示例 3:输入:rating = [1,2,3,4]、输出:4
提示:n == rating.length、1 <= n <= 200、1 <= rating[i] <= 10^5
题解
一:暴力法,时间复杂度O(n^3)
二:固定中间的,再看他前面和后面有几个比他大的和比他小的,时间复杂度O(n^2)。
class Solution(object):
def numTeams(self, rating):
"""
:type rating: List[int]
:rtype: int
"""
ans, n = 0, len(rating)
for i in range(1, n - 1):
l_lt, l_gt = 0, 0
for j in range(i):
if rating[j] > rating[i]:
l_gt += 1
elif rating[j] < rating[i]:
l_lt += 1
r_lt, r_gt = 0, 0
for j in range(i + 1, n):
if rating[j] > rating[i]:
r_gt += 1
elif rating[j] < rating[i]:
r_lt += 1
ans += l_lt * r_gt + l_gt * r_lt
return ans
三:树状数组,参见《算法竞赛入门经典训练指南》P194,个人感觉讲的还是挺赞的,时间复杂度O(nlgm),n是rating的长度,m是rating的最大值。空间复杂度O(m)。
class Solution(object):
def numTeams(self, rating):
def add(rec, i, num):
while i < len(rec):
rec[i] += num
i += (i & (-i))
def get(rec, i):
ans = 0
while i > 0:
ans += rec[i]
i -= (i & (-i))
return ans
max_num, n = max(rating), len(rating)
rec = [0] * (max_num + 1)
left_less =[0] * n
left_large = [0] * n
for i in range(n):
left_less[i] = get(rec, rating[i])
add(rec, rating[i], 1)
left_large[i] = i - left_less[i]
rec = [0] * (max_num + 1)
right_less =[0] * n
right_large = [0] * n
for i in range(n - 1, -1, -1):
right_less[i] = get(rec, rating[i])
add(rec, rating[i], 1)
right_large[i] = n - i - right_less[i] - 1
ans = 0
for i in range(1, n - 1):
ans += left_less[i] * right_large[i] + left_large[i] * right_less[i]
return ans
四:针对三的优化,因为相对于最大值来说,rating的规模是比较小的,可以进行压缩,让时间复杂度O(nlgn),空间复杂度O(n)。参见官方题解方法三,离散化树状数组https://leetcode-cn.com/problems/count-number-of-teams/solution/tong-ji-zuo-zhan-dan-wei-shu-by-leetcode-solution/。
class Solution(object):
def numTeams(self, rating):
def add(rec, i, num):
while i < len(rec):
rec[i] += num
i += (i & (-i))
def get(rec, i):
ans = 0
while i > 0:
ans += rec[i]
i -= (i & (-i))
return ans
def get_id(arr, target):
l, r = 0, len(arr)
while l < r:
mid = l + (r - l) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
l = mid + 1
else:
r = mid
n = len(rating)
rec = [0] * (200 + 1)
left_less =[0] * n
left_large = [0] * n
rating_copy = sorted(rating)
for i in range(n):
idx = get_id(rating_copy, rating[i]) + 1
left_less[i] = get(rec, idx)
add(rec, idx, 1)
left_large[i] = i - left_less[i]
rec = [0] * (200 + 1)
right_less =[0] * n
right_large = [0] * n
for i in range(n - 1, -1, -1):
idx = get_id(rating_copy, rating[i]) + 1
right_less[i] = get(rec, idx)
add(rec, idx, 1)
right_large[i] = n - i - right_less[i] - 1
ans = 0
for i in range(1, n - 1):
ans += left_less[i] * right_large[i] + left_large[i] * right_less[i]
return ans
357. 计算各个位数不同的数字个数
https://leetcode-cn.com/problems/count-numbers-with-unique-digits/
给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n 。
示例:
输入: 2
输出: 91
解释: 答案应为除去 11,22,33,44,55,66,77,88,99 外,在 [0,100) 区间内的所有数字。
题解
一:数学方法,我们可以容易的推算出固定一个n位的符合的数字的个数,然后把小于等于n位的所有数字的个数加一下。
解题思路
参数定义
n:数字的位数
i:遍历到的整数含i个数字
res:返回值,数字为1~i个的整数中不含重复数字的总和
cur:整数位数为i时无重复数字的个数
k:0~9中剩余可选数字的个数
思路
由于数字只有0~9十个,所以当n大于10时,必然会有重复,此时不同数字的结果和n为10时相同
当n=0时,满足条件的只有0,即个数为res=1
当n=1时,满足条件的数为0~9,即个数为res=10
当n=2时,数字包含两位时,第一位可选1~9中的数C(9,1),第二位可选0~10中除去第一位选择的数C(9,1),即cur=9*9,再加上一位数字的情况res+=cur,即res=10+81=91
当n=3时,数字包含三位时,第一位第一位可选1~9中的数C(9,1),第二位可选0~9中除去第一位选择的数C(9,1),第三位可选0~9中除去前两位选择的数C(8,1),即cur=9*9*8,再加上一位数字和两位数字的情况res+=cur,即res=91+648=739
复杂度分析
时间复杂度:O(N)
空间复杂度:O(1)
class Solution(object):
def countNumbersWithUniqueDigits(self, n):
"""
:type n: int
:rtype: int
"""
"""固定位数n符合条件的数字的个数"""
def perm(n):
if n == 0:
return 1
elif n > 10:
return 0
res = 9
# 9, 9, 8, 7
# 9, 8, 7
for i in range(0, n - 1):
res *= (9 - i)
return res
ans = 0
for i in range(n + 1):
ans += perm(i)
return ans
二:动态规划,其实同数学方法差不多,还可以优化一下空间。这边当n>=1时dp[1:]表示不同的数位,一共n个数位。
class Solution(object):
def countNumbersWithUniqueDigits(self, n):
if n == 0:
return 1
dp = [0] * (n + 1)
dp[0], dp[1] = 1, 9
ans = 10
for i in range(1, n):
dp[i + 1] = dp[i] * (10 - i)
ans += dp[i + 1]
if dp[i] == 0:
return ans
return ans
class Solution(object):
def countNumbersWithUniqueDigits(self, n):
if n == 0:
return 1
ans, dp = 10, 9
for i in range(1, n):
dp *= (10 - i)
ans += dp
if dp == 0:
return ans
return ans
1291. 顺次数
https://leetcode-cn.com/problems/sequential-digits/
我们定义「顺次数」为:每一位上的数字都比前一位上的数字大 1 的整数。请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表(从小到大排序)。
示例 1:输出:low = 100, high = 300,输出:[123,234]
示例 2:输出:low = 1000, high = 13000,输出:[1234,2345,3456,4567,5678,6789,12345]
提示:10 <= low <= high <= 10^9
题解
一:还是同上一题一样的思路固定位数,每当固定数据位数为n时,我们就能很方便的列出该位数的所有数据。
class Solution(object):
def sequentialDigits(self, low, high):
"""
:type low: int
:type high: int
:rtype: List[int]
"""
# 1 2 3 , 9 - n + 1
# 2 3 4 ,
# n位数符合要求的数据
def cnt(n, low, high, l_n, h_n):
ans = []
if n != l_n and n != h_n:
for i in range(1, 10 - n + 1):
ans.append(int("".join(str(i + j) for j in range(n))))
else:
for i in range(1, 10 - n + 1):
num = int("".join(str(i + j) for j in range(n)))
if int(low) <= num <= int(high):
ans.append(num)
return ans
l_n, h_n = len(str(low)), len(str(high))
ans = []
low, high = str(low), str(high)
for i in range(l_n, h_n + 1):
l = cnt(i, low, high, l_n, h_n)
ans.extend(l)
return ans
二:枚举,转自官方题解, https://leetcode-cn.com/problems/sequential-digits/solution/shun-ci-shu-by-leetcode-solution/, 枚举。我们可以枚举所有的「顺次数」,并依次判断它们是否在 [low, high] 的范围内。
具体地,我们首先枚举「顺次数」的最高位数字 i,随后递增地枚举「顺次数」的最低位数字 j,需要满足 j > i。对于每一组 (i, j),我们可以得到其对应的「顺次数」num,如果 num 在 [low, high] 的范围内,就将其加入答案中。
在枚举完所有的「顺次数」后,我们将答案进行排序,就可以得到最终的结果。
复杂度分析:时间复杂度:O(1)。根据定义,每一组满足的 (i, j) 就对应了一个「顺次数」,那么「顺次数」的数量为
个,可以视作一个常数。因此时间复杂度为 O(1)。
lass Solution:
def sequentialDigits(self, low: int, high: int) -> List[int]:
ans = list()
for i in range(1, 10):
num = i
for j in range(i + 1, 10):
num = num * 10 + j
if low <= num <= high:
ans.append(num)
return sorted(ans)