给定一个排序的整数数组 nums ,其中元素的范围在 闭区间 [lower, upper] 当中,返回不包含在数组中的缺失区间。
class Solution:
def findMissingRanges(self, nums: List[int], lower: int, upper: int) -> List[str]:
length = len(nums)
new_list = []
if length == 0:
if upper - lower >= 1:
strr = str(lower) +"->"+str(upper)
else:
strr = str(lower)
new_list.append(strr)
return new_list
if nums[0] - lower >= 2:
strr = str(lower) + "->" + str(nums[0]-1)
lower = nums[0]
new_list.append(strr)
elif nums[0] - lower == 1:
strr = str(lower)
lower = nums[0]
new_list.append(strr)
for i in range(1, length):
strr = ""
if nums[i] - lower > 2:
strr = str(lower+1) + "->" + str(nums[i]-1)
lower = nums[i]
elif nums[i] - lower == 2:
strr = str(lower+1)
lower = nums[i]
elif nums[i] - lower == 1:
lower = nums[i]
continue
else:
continue
new_list.append(strr)
if upper - nums[length-1]>= 2:
strr = str(nums[length-1]+1) + "->" + str(upper)
new_list.append(strr)
elif upper - nums[length-1] == 1:
strr = str(upper)
new_list.append(strr)
return new_list
给你一个整数数组 nums 和整数 k ,返回最大和 sum ,满足存在 i < j 使得 nums[i] + nums[j] = sum 且 sum < k 。如果没有满足此等式的 i,j 存在,则返回 -1 。
class Solution:
def twoSumLessThanK(self, nums: List[int], k: int) -> int:
max_sum = 0
length = len(nums)
for i in range(length-1):
for j in range(i+1, length):
sum_n = nums[i] + nums[j]
if sum_n >= k:
continue
elif sum_n > max_sum:
# print(k, sum_n)
max_sum = sum_n
if max_sum == 0:
return -1
return max_sum
设计一个接收整数流的数据结构,该数据结构支持检查是否存在两数之和等于特定值。
实现 TwoSum 类:
TwoSum() 使用空数组初始化 TwoSum 对象
void add(int number) 向数据结构添加一个数 number
boolean find(int value) 寻找数据结构中是否存在一对整数,使得两数之和与给定的值相等。如果存在,返回 true ;否则,返回 false 。
class TwoSum:
def __init__(self):
self.nums = []
# self.sums = []
self.sorted = False
def add(self, number: int) -> None:
self.nums.append(number)
self.sorted = False
return None
def find(self, value: int) -> bool:
# length = len(self.nums)
## 二分查找
if self.sorted == False:
self.nums.sort()
self.sorted = True
low, high = 0, len(self.nums)-1
while low < high:
num = self.nums[low] + self.nums[high]
if num < value:
low+=1
elif num > value:
high-=1
else:
return True
return False
# Your TwoSum object will be instantiated and called as such:
# obj = TwoSum()
# obj.add(number)
# param_2 = obj.find(value)
给定一个不为空的二叉搜索树和一个目标值 target,请在该二叉搜索树中找到最接近目标值 target 的数值。
注意:
给定的目标值 target 是一个浮点数
题目保证在该二叉搜索树中只会存在一个最接近目标值的数
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def closestValue(self, root: Optional[TreeNode], target: float) -> int:
if not root:
return None
small_diff = float("inf")
close_num = root.val
while root:
diff = abs(root.val - target)
if diff < small_diff:
small_diff = diff
close_num = root.val
if root.val > target:
root = root.left
elif root.val < target:
root = root.right
else:
return root.val
return close_num
给你一个字符串 s ,请你删去其中的所有元音字母 ‘a’,‘e’,‘i’,‘o’,‘u’,并返回这个新字符串。
class Solution:
def removeVowels(self, s: str) -> str:
l = len(s)
ss = "aeiou"
new_s = ""
for i in range(l):
if s[i] not in ss:
new_s += s[i]
return new_s
给定一个字符串数组 wordDict 和两个已经存在于该数组中的不同的字符串 word1 和 word2 。返回列表中这两个单词之间的最短距离。
class Solution:
def shortestDistance(self, wordsDict: List[str], word1: str, word2: str) -> int:
index1, index2 = -1,-1
index = len(wordsDict)
for idx,x in enumerate(wordsDict):
if x == word1:
index1=idx
if x == word2:
index2=idx
if index1 != -1 and index2 != -1:
reduce = abs(index1 - index2)
if reduce < index:
index = reduce
return index
中心对称数是指一个数字在旋转了 180 度之后看起来依旧相同的数字(或者上下颠倒地看)。
请写一个函数来判断该数字是否是中心对称数,其输入将会以一个字符串的形式来表达数字。
class Solution:
def isStrobogrammatic(self, num: str) -> bool:
dic = {"0":"0","1":"1", "6":"9", "9":"6", "8":"8"}
dic1 = {"0":"0", "1":"1", "8":"8"}
if len(num) <= 1:
if num in dic1.keys():
return True
else:
return False
new_num = ""
for i in range(len(num)):
if num[i] not in dic.keys():
return False
else:
new_num = dic[num[i]] + new_num
if str(new_num) == num:
return True
return False
class Solution:
def anagramMappings(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = []
for x in nums1:
res.append(nums2.index(x))
return res
请你设计一个日志系统,可以流式接收消息以及它的时间戳。每条 不重复 的消息最多只能每 10 秒打印一次。也就是说,如果在时间戳 t 打印某条消息,那么相同内容的消息直到时间戳变为 t + 10 之前都不会被打印。
所有消息都按时间顺序发送。多条消息可能到达同一时间戳。
实现 Logger 类:
Logger() 初始化 logger 对象
bool shouldPrintMessage(int timestamp, string message) 如果这条消息 message 在给定的时间戳 timestamp 应该被打印出来,则返回 true ,否则请返回 false 。
链接:https://leetcode.cn/problems/logger-rate-limiter
class Logger:
def __init__(self):
self.dic = dict()
def shouldPrintMessage(self, timestamp: int, message: str) -> bool:
if message not in self.dic.keys():
self.dic[message] = timestamp + 10
return True
else:
if timestamp >= self.dic[message]:
self.dic[message] = timestamp + 10
return True
else:
return False
# Your Logger object will be instantiated and called as such:
# obj = Logger()
# param_1 = obj.shouldPrintMessage(timestamp,message)
设计并实现一个迭代压缩字符串的数据结构。给定的压缩字符串的形式是,每个字母后面紧跟一个正整数,表示该字母在原始未压缩字符串中出现的次数。
设计一个数据结构,它支持如下两种操作: next 和 hasNext。
next() - 如果原始字符串中仍有未压缩字符,则返回下一个字符,否则返回空格。
hasNext() - 如果原始字符串中存在未压缩的的字母,则返回true,否则返回false。
链接:https://leetcode.cn/problems/design-compressed-string-iterator
class StringIterator:
def __init__(self, compressedString: str):
tmp = ""
nums = ""
self.compressedString = []
self.nums = []
for s in compressedString:
if s.isdigit():
nums+=s
else:
if tmp!="" and nums!="":
num = 0
for ss in nums:
num = num*10 + int(ss)
self.compressedString.append(tmp)
self.nums.append(num)
nums = ""
tmp = s
if nums!="":
num = 0
for ss in nums:
num = num*10 + int(ss)
self.compressedString.append(tmp)
self.nums.append(num)
def next(self) -> str:
if not self.nums:
return " "
if len(self.compressedString) >= 1 and self.nums[0]!=0:
a = self.compressedString[0]
self.nums[0]-=1
if self.nums[0]==0:
self.nums.pop(0)
self.compressedString.pop(0)
return a
def hasNext(self) -> bool:
if len(self.compressedString)>=1: return True
return False
我们可以将一个句子表示为一个单词数组,例如,句子 “I am happy with leetcode” 可以表示为 arr = [“I”,“am”,happy",“with”,“leetcode”]
给定两个句子 sentence1 和 sentence2 分别表示为一个字符串数组,并给定一个字符串对 similarPairs ,其中 similarPairs[i] = [xi, yi] 表示两个单词 xi and yi 是相似的。
如果 sentence1 和 sentence2 相似则返回 true ,如果不相似则返回 false 。
两个句子是相似的,如果:
它们具有 相同的长度 (即相同的字数)
sentence1[i] 和 sentence2[i] 是相似的
请注意,一个词总是与它自己相似,也请注意,相似关系是不可传递的。例如,如果单词 a 和 b 是相似的,单词 b 和 c 也是相似的,那么 a 和 c 不一定相似 。
链接:https://leetcode.cn/problems/sentence-similarity
class Solution:
def areSentencesSimilar(self, sentence1: List[str], sentence2: List[str], similarPairs: List[List[str]]) -> bool:
if len(sentence1)!=len(sentence2):
return False
for x, y in zip(sentence1, sentence2):
if x!=y:
if [x,y] not in similarPairs and [y,x] not in similarPairs:
return False
return True
RGB 颜色 “#AABBCC” 可以简写成 “#ABC” 。
例如,“#15c” 其实是 “#1155cc” 的简写。
现在,假如我们分别定义两个颜色 “#ABCDEF” 和 “#UVWXYZ”,则他们的相似度可以通过这个表达式 -(AB - UV)^2 - (CD - WX)^2 - (EF - YZ)^2 来计算。
那么给你一个按 “#ABCDEF” 形式定义的字符串 color 表示 RGB 颜色,请你以字符串形式,返回一个与它相似度最大且可以简写的颜色。(比如,可以表示成类似 “#XYZ” 的形式)
任何 具有相同的(最大)相似度的答案都会被视为正确答案。
链接:https://leetcode.cn/problems/similar-rgb-color
class Solution:
def similarRGB(self, color: str) -> str:
nums = [str(i) for i in range(10)] + ["a","b","c","d","e","f"]
def str2int(s):
num = 0
for ss in s:
num = num*16 + nums.index(ss)
return num
AB = (color[1:3])
a = str2int(AB)
CD = (color[3:5])
b = str2int(CD)
EF = (color[5:7])
c = str2int(EF)
def str2list(s):
if s[0] == str(0):
return ["0","1"]
elif s[0] == "f":
return ["e","f"]
else:
index = nums.index(s[0])
return [nums[index-1], nums[index], nums[index+1]]
minm = float("inf")
ans = ""
for x in str2list(AB):
for y in nums:
for z in nums:
u = str2int(x*2)
v = str2int(y*2)
w = str2int(z*2)
tmp = -(a-u)**2-(b-v)**2-(c-w)**2
if abs(tmp) < minm:
# print(a,u,b,v,c,w)
minm = abs(tmp)
ans = x*2+y*2+z*2
return "#" + ans
给定一个数字 N,当它满足以下条件的时候返回 true:
原数字旋转 180° 以后可以得到新的数字。
如 0, 1, 6, 8, 9 旋转 180° 以后,得到了新的数字 0, 1, 9, 8, 6 。
2, 3, 4, 5, 7 旋转 180° 后,得到的不是数字。
易混淆数 (confusing number) 在旋转180°以后,可以得到和原来不同的数,且新数字的每一位都是有效的。
链接:https://leetcode.cn/problems/confusing-number
class Solution:
def confusingNumber(self, n: int) -> bool:
dic = {"0":"0","1":"1","6":"9","8":"8","9":"6"}
s = str(n)
new_s = ""
for idx,ss in enumerate(s):
if ss not in dic:
return False
new_s += dic[ss]
if new_s[::-1] == s:
return False
return True
class Solution:
def fixedPoint(self, arr: List[int]) -> int:
n = len(arr)
for i in range(n):
if i == arr[i]:
return arr[i]
return -1
class Solution:
def sumOfDigits(self, nums: List[int]) -> int:
nums.sort()
num = nums[0]
s = str(num)
res = 0
for ss in s:
res += int(ss)
if res%2 == 0:
return 1
else: return 0
给出 字符串 text 和 字符串列表 words, 返回所有的索引对 [i, j] 使得在索引对范围内的子字符串 text[i]…text[j](包括 i 和 j)属于字符串列表 words。
链接:https://leetcode.cn/problems/index-pairs-of-a-string
class Solution:
def indexPairs(self, text: str, words: List[str]) -> List[List[int]]:
res = []
n = len(text)
for i in range(n):
for j in range(i,n):
for word in words:
if text[i:j+1] == word:
res.append([i,j])
break
return res
给你一个不同学生的分数列表 items,其中 items[i] = [IDi, scorei] 表示 IDi 的学生的一科分数,你需要计算每个学生 最高的五科 成绩的 平均分。
返回答案 result 以数对数组形式给出,其中 result[j] = [IDj, topFiveAveragej] 表示 IDj 的学生和他 最高的五科 成绩的 平均分。result 需要按 IDj 递增的 顺序排列 。
学生 最高的五科 成绩的 平均分 的计算方法是将最高的五科分数相加,然后用 整数除法 除以 5 。
链接:https://leetcode.cn/problems/high-five
class Solution:
def highFive(self, items: List[List[int]]) -> List[List[int]]:
dic = defaultdict(list)
for it in items:
dic[it[0]].append(it[1])
res = []
for k,v in dic.items():
tmp = dic[k]
tmp.sort(key=lambda x:-x)
res.append([k, sum(tmp[:5])//5])
res.sort(key = lambda x:x[0])
return res
闰年是公历中的名词。闰年分为普通闰年和世纪闰年,闰年的定义:
普通闰年:公历年份是 4 的倍数,且不是 100 的倍数的,为闰年(如 2004 年就是闰年)。
世纪闰年:公历年份是整百数的,必须是 400 的倍数才是世纪闰年(如 1900 年不是世纪闰年,2000 年是世纪闰年)。
class Solution:
def numberOfDays(self, year: int, month: int) -> int:
Id = 1
if (year % 100 != 0 and year % 4 == 0) or (year % 400 == 0):
Id = 1
else:
Id = 0
month1 = [1,3,5,7,8,10,12]
month2 = [2,4,6,8,10]
if month == 2:
if Id == 1:
return 29
else:
return 28
else:
if month in month1:
return 31
else:
return 30
给你一个整数数组 A,请找出并返回在该数组中仅出现一次的最大整数。
如果不存在这个只出现一次的整数,则返回 -1。
class Solution:
def largestUniqueNumber(self, nums: List[int]) -> int:
dic = defaultdict(int)
for num in nums:
dic[num] += 1
# print(dic)
l = []
for k,v in dic.items():
if v==1:
l.append(k)
if not l:
return -1
l.sort()
return l[-1]
给你一个整数 n ,让你来判定他是否是 阿姆斯特朗数,是则返回 true,不是则返回 false。
假设存在一个 k 位数 n ,其每一位上的数字的 k 次幂的总和也是 n ,那么这个数是阿姆斯特朗数 。
链接:https://leetcode.cn/problems/armstrong-number
class Solution:
def isArmstrong(self, n: int) -> bool:
k = len(str(n))
nums = []
for s in str(n):
nums.append(int(s))
m = 0
for x in nums:
m += x**k
return m==n
给出一个按 非递减 顺序排列的数组 nums,和一个目标数值 target。假如数组 nums 中绝大多数元素的数值都等于 target,则返回 True,否则请返回 False。
所谓占绝大多数,是指在长度为 N 的数组中出现必须 超过 N/2 次。
链接:https://leetcode.cn/problems/check-if-a-number-is-majority-element-in-a-sorted-array
class Solution:
def isMajorityElement(self, nums: List[int], target: int) -> bool:
dic = defaultdict(int)
tmp = 0
for num in nums:
dic[num] += 1
if dic[num]>len(nums)//2:
tmp = num
return tmp == target
我们定制了一款特殊的键盘,所有的键都 排列在一行上 。
给定一个长度为 26 的字符串 keyboard ,来表示键盘的布局(索引从 0 到 25 )。一开始,你的手指在索引 0 处。要输入一个字符,你必须把你的手指移动到所需字符的索引处。手指从索引 i 移动到索引 j 所需要的时间是 |i - j|。
您需要输入一个字符串 word 。写一个函数来计算用一个手指输入需要多少时间。
链接:https://leetcode.cn/problems/single-row-keyboard
class Solution:
def calculateTime(self, keyboard: str, word: str) -> int:
dic = defaultdict(int)
for idx,num in enumerate(keyboard):
dic[num] = idx
tmp = 0
time = 0
for s in word:
time += abs(dic[s]-tmp)
tmp = dic[s]
return time
你的好友是一位健身爱好者。前段日子,他给自己制定了一份健身计划。现在想请你帮他评估一下这份计划是否合理。
他会有一份计划消耗的卡路里表,其中 calories[i] 给出了你的这位好友在第 i 天需要消耗的卡路里总量。
为了更好地评估这份计划,对于卡路里表中的每一天,你都需要计算他 「这一天以及之后的连续几天」 (共 k 天)内消耗的总卡路里 T:
如果 T < lower,那么这份计划相对糟糕,并失去 1 分;
如果 T > upper,那么这份计划相对优秀,并获得 1 分;
否则,这份计划普普通通,分值不做变动。
请返回统计完所有 calories.length 天后得到的总分作为评估结果。
注意:总分可能是负数。
链接:https://leetcode.cn/problems/diet-plan-performance
class Solution:
def dietPlanPerformance(self, calories: List[int], k: int, lower: int, upper: int) -> int:
res = 0
idx = 0
cur = sum(calories[:k])
pre = calories[idx+k-1]
tmp = calories[idx+k-1]
while idx + k <= len(calories):
tmp = calories[idx+k-1]
cur = cur - pre + tmp
pre = calories[idx]
if cur < lower:
res -= 1
elif cur > upper:
res += 1
idx += 1
return res
给你一个字符串 s,返回 只含 单一字母 的子串个数 。
class Solution:
def countLetters(self, s: str) -> int:
ans = 0
dic = defaultdict(int)
for i in range(len(s)):
cur = s[i]
dic[cur] += 1
for j in range(i+1, len(s)):
if s[j]!=cur:
break
dic[s[i:j+1]] += 1
for k,v in dic.items():
ans += v
return ans
你有一些苹果和一个可以承载 5000 单位重量的篮子。
给定一个整数数组 weight ,其中 weight[i] 是第 i 个苹果的重量,返回 你可以放入篮子的最大苹果数量 。
链接:https://leetcode.cn/problems/how-many-apples-can-you-put-into-the-basket
class Solution:
def maxNumberOfApples(self, weight: List[int]) -> int:
weight.sort()
ans = 0
cur = 0
print(weight)
for w in weight:
cur += w
if cur > 5000:
return ans
ans += 1
return ans
class Solution:
def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]:
res = []
for x in arr1:
if x in arr2 and x in arr3:
res.append(x)
return res
在某个数组 arr 中,值符合等差数列的数值规律:在 0 <= i < arr.length - 1 的前提下,arr[i+1] - arr[i] 的值都相等。
我们会从该数组中删除一个 既不是第一个 也 不是最后一个的值,得到一个新的数组 arr。
给你这个缺值的数组 arr,返回 被删除的那个数 。
链接:https://leetcode.cn/problems/missing-number-in-arithmetic-progression
class Solution:
def missingNumber(self, arr: List[int]) -> int:
d = (arr[-1] - arr[0])//len(arr)
print(d)
for i in range(1, len(arr)):
if arr[i] - arr[i-1] != d:
return arr[i-1]+d
return arr[0]
首先,给你一个初始数组 arr。然后,每天你都要根据前一天的数组生成一个新的数组。
第 i 天所生成的数组,是由你对第 i-1 天的数组进行如下操作所得的:
假如一个元素小于它的左右邻居,那么该元素自增 1。
假如一个元素大于它的左右邻居,那么该元素自减 1。
首、尾元素 永不 改变。
过些时日,你会发现数组将会不再发生变化,请返回最终所得到的数组。
链接:https://leetcode.cn/problems/array-transformation
class Solution:
def transformArray(self, arr: List[int]) -> List[int]:
tmp = []
while arr != tmp:
tmp = arr
cur = arr[:]
for i in range(1, len(arr)-1):
if arr[i-1]>arr[i] and arr[i]<arr[i+1]:
cur[i] += 1
elif arr[i-1]<arr[i] and arr[i]>arr[i+1]:
cur[i] -= 1
arr = cur
return arr
你有一个十进制数字,请按照此规则将它变成「十六进制魔术数字」:首先将它变成字母大写的十六进制字符串,然后将所有的数字 0 变成字母 O ,将数字 1 变成字母 I 。
如果一个数字在转换后只包含 {“A”, “B”, “C”, “D”, “E”, “F”, “I”, “O”} ,那么我们就认为这个转换是有效的。
给你一个字符串 num ,它表示一个十进制数 N,如果它的十六进制魔术数字转换是有效的,请返回转换后的结果,否则返回 “ERROR” 。
链接:https://leetcode.cn/problems/hexspeak
class Solution:
def toHexspeak(self, num: str) -> str:
dic = {'0':'O','1':'I'}
l = ['0','1','a','b','c','d','e','f']
res = ''
s = 0
for x in num:
s = s*10 + int(x)
num = s
num_new = hex(num)[2:]
for ss in num_new:
if ss not in l:
return 'ERROR'
if ss in dic:
res += dic[ss]
else:
res += ss.upper()
return res
整数可以被看作是其因子的乘积。
例如:
8 = 2 x 2 x 2;
= 2 x 4.
请实现一个函数,该函数接收一个整数 n 并返回该整数所有的因子组合。
链接:https://leetcode.cn/problems/factor-combinations
class Solution:
def getFactors(self, n: int) -> List[List[int]]:
def dfs(l, m):
res = []
for i in range(l, int(sqrt(m))+1):
if m%i == 0:
res.append([i, m//i])
for sub in dfs(i, m//i):
res.append([i] + sub)
return res
if n<=3:
return []
return dfs(2, n)
给定一个字符串,对该字符串可以进行 “移位” 的操作,也就是将字符串中每个字母都变为其在字母表中后续的字母,比如:“abc” -> “bcd”。这样,我们可以持续进行 “移位” 操作,从而生成如下移位序列:
“abc” -> “bcd” -> … -> “xyz”
给定一个包含仅小写字母字符串的列表,将该列表中所有满足 “移位” 操作规律的组合进行分组并返回
链接:https://leetcode.cn/problems/group-shifted-strings
class Solution:
def groupStrings(self, strings: List[str]) -> List[List[str]]:
def hash(string):
if len(string)>1:
return tuple((ord(string[i])-ord(string[i-1]))%26 for i in range(1,len(string)))
else:
return 0
res = defaultdict(list)
for l in strings:
res[hash(l)].append(l)
return list(res.values())
给定编号从 0 到 n - 1 的 n 个结点。给定一个整数 n 和一个 edges 列表,其中 edges[i] = [ai, bi] 表示图中节点 ai 和 bi 之间存在一条无向边。
如果这些边能够形成一个合法有效的树结构,则返回 true ,否则返回 false 。
链接:https://leetcode.cn/problems/graph-valid-tree
class Solution:
def validTree(self, n: int, edges: List[List[int]]) -> bool:
arr = [i for i in range(n)]
cluster = n
def findFather(i):
if arr[i] == i:
return i
return findFather(arr[i])
def union(x, y):
x = findFather(x)
y = findFather(y)
if x == y:
return True
else:
arr[y] = x
return False
for i,j in edges:
res = union(i, j)
if res:
return False
else:
cluster -= 1
return False if cluster != 1 else True
你有一个包含 n 个节点的图。给定一个整数 n 和一个数组 edges ,其中 edges[i] = [ai, bi] 表示图中 ai 和 bi 之间有一条边。
返回 图中已连接分量的数目 。
链接:https://leetcode.cn/problems/number-of-connected-components-in-an-undirected-graph
class Solution:
def countComponents(self, n: int, edges: List[List[int]]) -> int:
arr = [i for i in range(n)]
def findFather(i):
if arr[i] == i:
return i
return findFather(arr[i])
def isConnect(i,j):
x = findFather(i)
y = findFather(j)
if x==y: return True
else:
arr[y] = x
return False
cluster = n
for i,j in edges:
if not isConnect(i, j):
cluster -= 1
return cluster
假设你是一个专业的狗仔,参加了一个 n 人派对,其中每个人被从 0 到 n - 1 标号。在这个派对人群当中可能存在一位 “名人”。所谓 “名人” 的定义是:其他所有 n - 1 个人都认识他/她,而他/她并不认识其他任何人。
现在你想要确认这个 “名人” 是谁,或者确定这里没有 “名人”。而你唯一能做的就是问诸如 “A 你好呀,请问你认不认识 B呀?” 的问题,以确定 A 是否认识 B。你需要在(渐近意义上)尽可能少的问题内来确定这位 “名人” 是谁(或者确定这里没有 “名人”)。
在本题中,你可以使用辅助函数 bool knows(a, b) 获取到 A 是否认识 B。请你来实现一个函数 int findCelebrity(n)。
派对最多只会有一个 “名人” 参加。若 “名人” 存在,请返回他/她的编号;若 “名人” 不存在,请返回 -1。
链接:https://leetcode.cn/problems/find-the-celebrity
# The knows API is already defined for you.
# return a bool, whether a knows b
# def knows(a: int, b: int) -> bool:
class Solution:
def findCelebrity(self, n: int) -> int:
for i in range(n):
for j in range(n):
if i!=j:
if knows(i, j): break
if not knows(j, i): break
else:
if j==n-1: return i
continue
if j==n-1: return i
return -1
给你一个的整数数组 nums, 将该数组重新排序后使 nums[0] <= nums[1] >= nums[2] <= nums[3]…
class Solution:
def wiggleSort(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
nums.sort()
for idx,x in enumerate(nums):
if idx %2 == 0 and idx != 0:
tmp = nums[idx-1]
nums[idx-1] = nums[idx]
nums[idx] = tmp
return nums
给你一棵指定的二叉树的根节点 root ,请你计算其中 最长连续序列路径 的长度。
最长连续序列路径 是依次递增 1 的路径。该路径,可以是从某个初始节点到树中任意节点,通过「父 - 子」关系连接而产生的任意路径。且必须从父节点到子节点,反过来是不可以的。
链接:https://leetcode.cn/problems/binary-tree-longest-consecutive-sequence
class Solution:
def longestConsecutive(self, root: TreeNode) -> int:
self.res = 0
def dfs(root):
if not root:
return 0
l,r = dfs(root.left),dfs(root.right)
ans = 1
if root.left and root.left.val == root.val+1:
ans = max(ans, l+1)
if root.right and root.right.val == root.val+1:
ans = max(ans, r+1)
self.res = max(ans, self.res)
return ans
dfs(root)
return self.res
给你一个二叉树的根结点,返回其结点按 垂直方向(从上到下,逐列)遍历的结果。
如果两个结点在同一行和列,那么顺序则为 从左到右。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def verticalOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
d = [root]
c = []
# i, j = 0, 0
if not root:
return []
dic = {root.val:[0,0]}
dic_new = defaultdict(list)
dic_new[0] = [root.val ]
while d:
c = d
d = []
while c:
a = c.pop(0)
i,j = dic[a.val]
if a.left:
dic[a.left.val] =[i+1, j-1]
dic_new[j-1].append(a.left.val)
d.append(a.left)
if a.right:
dic[a.right.val] = [i+1, j+1]
dic_new[j+1].append(a.right.val)
d.append(a.right)
dic_new = sorted(dic_new.items(), key=lambda x:x[0])
res = []
for k, v in dic_new:
res.append(v)
return res
给定一个数组 nums 和一个目标值 k,找到和等于 k 的最长连续子数组长度。如果不存在任意一个符合要求的子数组,则返回 0。
class Solution:
def maxSubArrayLen(self, nums: List[int], k: int) -> int:
n = len(nums)
indexs = defaultdict(int)
indexs[0] = 0
sums = 0
res = 0
for i in range(n):
sums = sums + nums[i]
if sums not in indexs:
indexs[sums] = i+1
if sums-k in indexs:
res = max(res, i - indexs[sums-k] + 1)
return res
假设你有一个长度为 n 的数组,初始情况下所有的数字均为 0,你将会被给出 k 个更新的操作。
其中,每个操作会被表示为一个三元组:[startIndex, endIndex, inc],你需要将子数组 A[startIndex … endIndex](包括 startIndex 和 endIndex)增加 inc。
请你返回 k 次操作后的数组。
链接:https://leetcode.cn/problems/range-addition
class Solution:
def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]:
nums = [0]*length
dic = defaultdict(int)
dic2 = defaultdict(str)
for l in updates:
dic[str(l)] += 1
dic2[str(l)] = l
# print(dic)
for k,v in dic.items():
s,e,i = dic2[k]
for j in range(s, e+1):
nums[j] += i*v
return nums
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def plusOne(self, head: ListNode) -> ListNode:
nums = 0
arr = []
head0 = ListNode(0)
while head:
nums = nums*10 + head.val
head = head.next
nums+=1
while nums != 0:
a = nums%10
nums = nums//10
arr.insert(0, a)
head = head0
while arr:
head0.next = ListNode()
head0 = head0.next
a = arr.pop(0)
head0.val = a
# tmp = ListNode()
return head.next
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def findLeaves(self, root: Optional[TreeNode]) -> List[List[int]]:
ans = defaultdict(list)
def dfs(root):
if not root:
return 0
l, r = dfs(root.left), dfs(root.right)
depth = max(l, r) + 1
ans[depth].append(root.val)
return depth
dfs(root)
return [v for k,v in ans.items()]
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderSuccessor(self, root: 'TreeNode', p: 'TreeNode') -> 'TreeNode':
res = []
def mid(root):
if not root:
return
mid(root.left)
res.append(root)
mid(root.right)
mid(root)
for i in range(len(res)):
if i+1 < len(res) and res[i] == p:
return res[i+1]
return None
你需要用一个包括括号和整数的字符串构建一棵二叉树。
输入的字符串代表一棵二叉树。它包括整数和随后的 0 、1 或 2 对括号。整数代表根的值,一对括号内表示同样结构的子树。
若存在子结点,则从左子结点开始构建。
链接:https://leetcode.cn/problems/construct-binary-tree-from-string
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def str2tree(self, s: str) -> TreeNode:
if len(s) == 0:
return None
if "(" not in s:
return TreeNode(int(s[:]))
pos = s.index('(')
# print(s, s.index('('))
root = TreeNode(int(s[:pos]))
start = pos
cnt = 0
for i in range(pos, len(s)):
if s[i] == '(': cnt+=1
if s[i] == ')': cnt-=1
if cnt==0 and start == pos:
root.left = self.str2tree(s[start+1:i])
start = i+1
elif cnt==0 and start != pos:
root.right = self.str2tree(s[start+1:i])
return root
class Solution:
def killProcess(self, pid: List[int], ppid: List[int], kill: int) -> List[int]:
subprocess = {kill}
res = {kill}
# tmp = subprocess
while subprocess:
tmp = set()
for i in range(len(pid)):
if ppid[i] in subprocess:
tmp.add(pid[i])
res = res.union(tmp)
subprocess = tmp
return list(res)
给你一个大小为 m x n 的图像 picture ,图像由黑白像素组成,‘B’ 表示黑色像素,‘W’ 表示白色像素,请你统计并返回图像中 黑色 孤独像素的数量。
黑色孤独像素 的定义为:如果黑色像素 ‘B’ 所在的同一行和同一列不存在其他黑色像素,那么这个黑色像素就是黑色孤独像素。
链接:https://leetcode.cn/problems/lonely-pixel-i
class Solution:
def findLonelyPixel(self, picture: List[List[str]]) -> int:
dic_x = []
dic_y = []
m = len(picture)
n = len(picture[0])
res = 0
row = defaultdict(int)
col = defaultdict(int)
for i in range(m):
for j in range(n):
if picture[i][j] == "B" :
row[i] += 1
col[j] += 1
for i in range(m):
for j in range(n):
if picture[i][j] == "W":
continue
elif picture[i][j] == "B" and (row[i]==1 and col[j]==1):
res+=1
return res
现有一个按 升序 排列的整数数组 nums ,其中每个数字都 互不相同 。
给你一个整数 k ,请你找出并返回从数组最左边开始的第 k 个缺失数字。
class Solution:
def missingElement(self, nums: List[int], k: int) -> int:
if len(nums)<=1:
return nums[0]+1
pre = nums[0]
for x in nums:
diff = x - pre - 1
if diff >= k:
return pre + k
elif diff == -1 and x == nums[0]:
continue
else:
k -= diff
pre = x
return nums[-1] + k
给你一个字符串 s 和一个整数 k ,请你找出 至多 包含 k 个 不同 字符的最长子串,并返回该子串的长度。
class Solution:
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
hash_map = defaultdict(int)
left, right = 0, 0
n = len(s)
res = 0
if len(s) <= k:
return len(s)
while right < n:
hash_map[s[right]] = right
right += 1
if len(hash_map) == k+1:
index = min(hash_map.values())
del hash_map[s[index]]
left = index + 1
res = max(res, right-left)
return res
给定一个 m x n 的二进制矩阵 mat ,返回矩阵中最长的连续1线段。
这条线段可以是水平的、垂直的、对角线的或者反对角线的。
class Solution:
def longestLine(self, mat: List[List[int]]) -> int:
m, n = len(mat), len(mat[0])
self.res = 0
for i in range(m):
for j in range(n):
if mat[i][j] == 1:
for dr, dc in [(1,0),(1,-1),(1,1),(0,1)]:
tmp = 1
nr, nc = dr+i, dc+j
while 0<=nr<m and 0<=nc<n and mat[nr][nc]==1:
tmp += 1
nr += dr
nc += dc
self.res = max(self.res, tmp)
return self.res
请设计一个类,使该类的构造函数能够接收一个字符串数组。然后再实现一个方法,该方法能够分别接收两个单词,并返回列表中这两个单词之间的最短距离。
实现 WordDistanc 类:
WordDistance(String[] wordsDict) 用字符串数组 wordsDict 初始化对象。
int shortest(String word1, String word2) 返回数组 worddict 中 word1 和 word2 之间的最短距离。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shortest-word-distance-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class WordDistance:
def __init__(self, wordsDict: List[str]):
self.wordsDict = wordsDict
self.word = defaultdict(list)
for idx, word in enumerate(self.wordsDict):
self.word[word].append(idx)
def shortest(self, word1: str, word2: str) -> int:
res = float("inf")
index1 = self.word[word1]
index2 = self.word[word2]
i, j = 0, 0
while i<len(index1) and j<len(index2):
res = min(res, abs(index1[i]-index2[j]))
if index1[i] > index2[j]:
j+=1
else:
i+=1
return res
给定一个整数 n ,返回所有长度为 n 的 中心对称数 。你可以以 任何顺序 返回答案。
中心对称数 是一个数字在旋转了 180 度之后看起来依旧相同的数字(或者上下颠倒地看)。
链接:https://leetcode.cn/problems/strobogrammatic-number-ii
class Solution:
def findStrobogrammatic(self, n: int) -> List[str]:
dic1 = {"0":"0", "1":"1", "6":"9", "8":"8", "9":"6"}
dic2 = {"0":"0", "1":"1", "8":"8"}
def dfs1(ans):
if len(ans) == n:
self.res.append(ans)
return
for k,v in dic1.items():
dfs1(k+ans+v)
def dfs2(ans):
if len(ans) == n:
self.res.append(ans)
return
for k,v in dic1.items():
dfs2(k+ans+v)
self.res = []
if n%2 == 0:
dfs1("")
else:
for k,v in dic2.items():
dfs2(k)
if n > 1:
for idx,x in enumerate(self.res):
if x[0]=="0":
self.res.pop(idx)
return self.res
给定两个字符串 s 和 t ,如果它们的编辑距离为 1 ,则返回 true ,否则返回 false 。
字符串 s 和字符串 t 之间满足编辑距离等于 1 有三种可能的情形:
往 s 中插入 恰好一个 字符得到 t
从 s 中删除 恰好一个 字符得到 t
在 s 中用 一个不同的字符 替换 恰好一个 字符得到 t
链接:https://leetcode.cn/problems/one-edit-distance
class Solution:
def isOneEditDistance(self, s: str, t: str) -> bool:
if abs(len(s)-len(t)) > 1:
return False
if s == t:
return False
i, j = 0, 0
while i<len(s) and j<len(t) and s[i] == t[j] :
i+=1
j+=1
if len(s) == len(t):
for z in range(i+1,len(s)):
if s[z] != t[z]:
return False
elif len(s) > len(t):
for z in range(j, len(t)):
if s[z+1] != t[z]:
return False
else:
for z in range(i, len(s)):
if s[z] != t[z+1]:
return False
return True
给定一个二叉树,统计该二叉树数值相同的子树个数。
同值子树是指该子树的所有节点都拥有相同的数值。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def countUnivalSubtrees(self, root: Optional[TreeNode]) -> int:
self.res = 0
def dfs(root):
if not root: return None
if not root.right and not root.left:
self.res += 1
return root.val
left = dfs(root.left)
right = dfs(root.right)
if left == right == root.val or (right is None and left == root.val) or (left is None and right ==root.val):
self.res += 1
return root.val
return inf
dfs(root)
return self.res
请设计并实现一个能够展开二维向量的迭代器。该迭代器需要支持 next 和 hasNext 两种操作。
class Vector2D:
def __init__(self, vec: List[List[int]]):
self.vec = [x for l in vec for x in l]
def next(self) -> int:
return self.vec.pop(0)
def hasNext(self) -> bool:
if len(self.vec) > 0:
return True
else: return False
# Your Vector2D object will be instantiated and called as such:
# obj = Vector2D(vec)
# param_1 = obj.next()
# param_2 = obj.hasNext()
给定一个长度为 n 的整数数组和一个目标值 target ,寻找能够使条件 nums[i] + nums[j] + nums[k] < target 成立的三元组 i, j, k 个数(0 <= i < j < k < n)。
链接:https://leetcode.cn/problems/3sum-smaller
class Solution:
def threeSumSmaller(self, nums: List[int], target: int) -> int:
self.res = 0
nums.sort()
if len(nums)<3:
if len(nums)==3 and sum(nums)<target:
return 1
else: return 0
if nums[0]>0 and nums[0]>target: return 0
def dfs(l, idx):
if len(l) == 3:
if sum(l) < target:
self.res+=1
return
for i in range(idx, len(nums)):
dfs(l+[nums[i]], i+1)
dfs([], 0)
return self.res
class Codec:
def encode(self, strs: List[str]) -> str:
"""Encodes a list of strings to a single string.
"""
encoded_str = ""
self.index = []
tmp = 0
for x in strs:
encoded_str += x
tmp += len(x)
self.index.append(tmp)
return encoded_str
def decode(self, s: str) -> List[str]:
"""Decodes a single string to a list of strings.
"""
decoded_str = []
pre = 0
for idx in self.index:
tmp = s[pre:idx]
pre = idx
decoded_str.append(tmp)
return decoded_str
给出两个一维的向量,请你实现一个迭代器,交替返回它们中间的元素。
class ZigzagIterator:
def __init__(self, v1: List[int], v2: List[int]):
self.v = []
i, j = 0, 0
while i<len(v1) and j<len(v2):
self.v.append(v1[i])
self.v.append(v2[j])
i+=1
j+=1
if i!=len(v1):
self.v += v1[i:]
if j!=len(v2):
self.v += (v2[j:])
def next(self) -> int:
return self.v.pop(0)
def hasNext(self) -> bool:
if len(self.v)>0: return True
else: return False
# Your ZigzagIterator object will be instantiated and called as such:
# i, v = ZigzagIterator(v1, v2), []
# while i.hasNext(): v.append(i.next())
有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,请你按下述规则为栅栏设计涂色方案:
每个栅栏柱可以用其中 一种 颜色进行上色。
相邻的栅栏柱 最多连续两个 颜色相同。
给你两个整数 k 和 n ,返回所有有效的涂色 方案数 。
链接:https://leetcode.cn/problems/paint-fence
class Solution:
def numWays(self, n: int, k: int) -> int:
if k == 1:
if n<=2:
return 1
else:
return 0
# if n == 1:
# return k
# dp[i][0]:与上一个颜色不一样
# dp[i][0] = dp[i-1][0]*(k-1) + dp[i-1][1]*k
# dp[i][1]:与上一个颜色一样
# dp[i][1] = dp[i-1][0]
dp = [[0, 0] for _ in range(n)]
dp[0][0], dp[0][1] = k, 0
for i in range(1, n):
dp[i][0] = (dp[i-1][0]+ dp[i-1][1])*(k-1)
dp[i][1] = dp[i-1][0]
print(dp[i])
return dp[n-1][0] + dp[n-1][1]
class Solution:
def wallsAndGates(self, rooms: List[List[int]]) -> None:
"""
Do not return anything, modify rooms in-place instead.
"""
#### DFS
# inf = 2**(31)-1
# m, n = len(rooms), len(rooms[0])
# # self.res = [[inf for _ in range(n)] for _ in range(m)]
# # res = [[inf for _ in range(n)] for _ in range(m)]
# # for i in range(m):
# # for j in range(n):
# # res[i][j] = rooms[i][j]
# def dfs(cur_i, cur_j, nums, vistied):
# if nums > rooms[cur_i][cur_j]:
# return
# rooms[cur_i][cur_j] = min(rooms[cur_i][cur_j], nums)
# print(nums, rooms[cur_i][cur_j], cur_i, cur_j)
# pathway = [(1,0),(0,1),(-1,0),(0,-1)]
# for i in range(4):
# dr, dc = pathway[i]
# nr, nc = dr+cur_i, dc+cur_j
# if 0<=nr
# vistied[nr][nc] = True
# dfs(nr, nc, nums+1, vistied)
# vistied[nr][nc] = False
# for i in range(m):
# for j in range(n):
# if rooms[i][j] == 0:
# vistied = [[False for _ in range(n)] for _ in range(m)]
# print(i, j)
# dfs(i, j, 0, vistied)
# # rooms = res.copy()
#### BFS
queue = []
m, n = len(rooms), len(rooms[0])
inf = 2**(31)-1
for i in range(m):
for j in range(n):
if rooms[i][j] == 0:
queue.append([i, j, 1])
while queue:
cur_i, cur_j, dist = queue.pop(0)
pathway = [(1,0),(0,1),(-1,0),(0,-1)]
for i in range(4):
dr, dc = pathway[i]
nr, nc = dr+cur_i, dc+cur_j
if 0<=nr<m and 0<=nc<n and rooms[nr][nc]==inf:
queue.append([nr, nc, dist+1])
rooms[nr][nc] = dist
单词的 缩写 需要遵循 <起始字母><中间字母数><结尾字母> 这样的格式。如果单词只有两个字符,那么它就是它自身的 缩写 。
以下是一些单词缩写的范例:
dog --> d1g 因为第一个字母 ‘d’ 和最后一个字母 ‘g’ 之间有 1 个字母
internationalization --> i18n 因为第一个字母 ‘i’ 和最后一个字母 ‘n’ 之间有 18 个字母
it --> it 单词只有两个字符,它就是它自身的 缩写
实现 ValidWordAbbr 类:
ValidWordAbbr(String[] dictionary) 使用单词字典 dictionary 初始化对象
boolean isUnique(string word) 如果满足下述任意一个条件,返回 true ;否则,返回 false :
字典 dictionary 中没有任何其他单词的 缩写 与该单词 word 的 缩写 相同。
字典 dictionary 中的所有 缩写 与该单词 word 的 缩写 相同的单词都与 word 相同 。
链接:https://leetcode.cn/problems/unique-word-abbreviation
class ValidWordAbbr:
def __init__(self, dictionary: List[str]):
self.dic1 = defaultdict(int)
self.dic2 = defaultdict(list)
for word in dictionary:
if len(word) == 2:
s = word
else:
s = word[0] + str(len(word)-2) + word[-1]
self.dic1[s] += 1
self.dic2[s].append(word)
def isUnique(self, word: str) -> bool:
if len(word) == 2:
s = word
else:
s = word[0] + str(len(word)-2) + word[-1]
if s not in self.dic1:
return True
else:
words = self.dic2[s]
for w in words:
if w!=word:
return False
return True
# Your ValidWordAbbr object will be instantiated and called as such:
# obj = ValidWordAbbr(dictionary)
# param_1 = obj.isUnique(word)
你和朋友玩一个叫做「翻转游戏」的游戏。游戏规则如下:
给你一个字符串 currentState ,其中只含 ‘+’ 和 ‘-’ 。你和朋友轮流将 连续 的两个 “++” 反转成 “–” 。当一方无法进行有效的翻转时便意味着游戏结束,则另一方获胜。默认每个人都会采取最优策略。
请你写出一个函数来判定起始玩家 是否存在必胜的方案 :如果存在,返回 true ;否则,返回 false 。
链接:https://leetcode.cn/problems/flip-game-ii
经典回朔
class Solution:
def canWin(self, currentState: str) -> bool:
s = list(currentState)
for i in range(len(s)-1):
if s[i] == '+' and s[i+1] == '+':
s[i] = '-'
s[i+1] = '-'
if self.canWin(''.join(s)) == False:
return True
s[i] = '+'
s[i+1] = '+'
return False
给定两个 稀疏矩阵 :大小为 m x k 的稀疏矩阵 mat1 和大小为 k x n 的稀疏矩阵 mat2 ,返回 mat1 x mat2 的结果。你可以假设乘法总是可能的。
链接:https://leetcode.cn/problems/sparse-matrix-multiplication
class Solution:
def multiply(self, mat1: List[List[int]], mat2: List[List[int]]) -> List[List[int]]:
m, k = len(mat1), len(mat1[0])
n = len(mat2[0])
res = [[0 for _ in range(n)]for _ in range(m)]
for i in range(m):
for j in range(n):
for h in range(k):
if (len(set(mat1[i][h:]))== 1 and sum(mat1[i][h:])==0) or (len(set(mat2[:][j]))== 1 and sum(mat2[:][j])==0):
break
res[i][j] += (mat1[i][h]*mat2[h][j])
return res
单词的 广义缩写词 可以通过下述步骤构造:先取任意数量的 不重叠、不相邻 的子字符串,再用它们各自的长度进行替换。
例如,“abcde” 可以缩写为:
“a3e”(“bcd” 变为 “3” )
“1bcd1”(“a” 和 “e” 都变为 “1”)
“5” (“abcde” 变为 “5”)
“abcde” (没有子字符串被代替)
然而,这些缩写是 无效的 :
“23”(“ab” 变为 “2” ,“cde” 变为 “3” )是无效的,因为被选择的字符串是相邻的
“22de” (“ab” 变为 “2” , “bc” 变为 “2”) 是无效的,因为被选择的字符串是重叠的
给你一个字符串 word ,返回 一个由 word 的所有可能 广义缩写词 组成的列表 。按 任意顺序 返回答案。
链接:https://leetcode.cn/problems/generalized-abbreviation
class Solution:
def generateAbbreviations(self, word: str) -> List[str]:
self.res = set()
def dfs(ans, idx, flag):
if idx>=len(word):
self.res.add(ans)
return
for j in range(idx, len(word)):
if flag == True:
dfs(ans+word[idx:j+1], j+1, False)
else:
dfs(ans+str(j-idx+1), j+1, True)
dfs(ans+word[idx:j+1], j+1, False)
dfs('', 0, False)
return list(self.res)