Leetcode简单题21~40
Posted xhw19950606
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode简单题21~40相关的知识,希望对你有一定的参考价值。
21.思路:sorted+列表推导式
#coding: UTF-8
#给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
#示例 1:
#输入:[-4,-1,0,3,10]
#输出:[0,1,9,16,100]
#me
class Solution(object):
def sortedSquares(self, A):
return sorted([i**2 for i in A])
22.思路:遇到‘D‘则放置当前列表中最大的数字
#给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length。
#返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i = 0, ..., N-1,都有:
# 如果 S[i] == "I",那么 A[i] < A[i+1]
# 如果 S[i] == "D",那么 A[i] > A[i+1]
# 示例 1:
# 输出:"IDID"
# 输出:[0,4,1,3,2]
# 示例 2:
# 输出:"III"
# 输出:[0,1,2,3]
#other
class Solution(object):
def diStringMatch(self, S):
res = list(range(len(S) + 1))
for i in range(len(S)):
if S[i] == ‘D‘:
res.insert(i, res.pop())
return res
23.思路:数学推导
# 你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
# 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
# 示例:
# 输入: 4
# 输出: false
# 解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
#me
class Solution(object):
def canWinNim(self, n):
if n%4==0:
return False
else:
return True
#others
class Solution1(object):
def canWinNim(self, n):
return bool(n % 4)
24.思路:最大数值的索引
# 我们把符合下列属性的数组 A 称作山脉:
# A.length >= 3
# 存在 0 < i < A.length - 1 使得A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
# 给定一个确定为山脉的数组,返回任何满足 A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1] 的 i 的值。
# 示例 1:
# 输入:[0,1,0]
# 输出:1
class Solution(object):
def peakIndexInMountainArray(self, A):
return A.index(max(A))
*25.思路:数学推导
# 爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
# 最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
# 选出任一 x,满足 0 < x < N 且 N % x == 0 。
# 用 N - x 替换黑板上的数字 N 。
# 如果玩家无法执行这些操作,就会输掉游戏。
# 只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。
# 示例 1:
# 输入:2
# 输出:true
# 解释:爱丽丝选择 1,鲍勃无法进行操作。
# 示例 2:
# 输入:3
# 输出:false
# 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
#other
# 归纳法:
# 基本思路:
# 1.最终结果应该是占到 2 的赢,占到 1 的输;
# 2.若当前为奇数,奇数的约数只能是奇数或者 1,因此下一个一定是偶数;
# 3.若当前为偶数, 偶数的约数可以是奇数可以是偶数也可以是 1,因此直接减 1,则下一个是奇数;
# 4.因此,奇则输,偶则赢。直接:
class Solution0(object):
def divisorGame(self, N):
return N%2==0
# 动态规划:
# 基本思路:
# 将所有的小于等于 N 的解都找出来,基于前面的,递推后面的。
# 状态转移: 如果 i 的约数里面有存在为 False 的(即输掉的情况),则当前 i 应为 True;如果没有,则为 False。
class Solution1(object):
def divisorGame(self, N):
target = [0 for i in range(N + 1)]
target[1] = 0 # 若爱丽丝抽到1,则爱丽丝输
if N <= 1:
return False
else:
target[2] = 1 # 若爱丽丝抽到2,则爱丽丝赢
for i in range(3, N + 1):
for j in range(1, i // 2):
# 若j是i的余数且target[i-j]为假(0)的话,则代表当前为真(1)
if i % j == 0 and target[i - j] == 0:
target[i] = 1
break
return target[N] == 1
26.思路:‘‘.join(list)+str[::-1]
#给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
#示例 1:
#输入: "Let‘s take LeetCode contest"
#输出: "s‘teL ekat edoCteeL tsetnoc"
#注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
#me
class Solution(object):
def reverseWords(self, s):
return ‘ ‘.join([ss[::-1] for ss in s.split(‘ ‘)])
27.思路:直述题意
# 给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
# 示例 1:
# 输入: [1,4,3,2]
# 输出: 4
# 解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
#me
class Solution0(object):
def arrayPairSum(self, nums):
newnums = sorted(nums)
return sum([newnums[2*i] for i in range(len(newnums)//2)])
#other
class Solution1(object):
def arrayPairSum(self,nums):
nums.sort()
return sum(nums[0::2])
28.思路:str.reverse()
# 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
# 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
# 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
# 示例 1:
# 输入:["h","e","l","l","o"]
# 输出:["o","l","l","e","h"]
# 示例 2:
# 输入:["H","a","n","n","a","h"]
# 输出:["h","a","n","n","a","H"]
#me
class Solution(object):
def reverseString(self, s):
s.reverse()
return s
29.思路:直述题意
# 你和朋友玩一个叫做「翻转游戏」的游戏,游戏规则:给定一个只有 + 和 - 的字符串。你和朋友轮流将 连续 的两个 "++" 反转成 "--"。 当一方无法进行有效的翻转时便意味着游戏结束,则另一方获胜。
# 请你写出一个函数,来计算出每个有效操作后,字符串所有的可能状态。
# 示例:
# 输入: s = "++++"
# 输出:
# [
# "--++",
# "+--+",
# "++--"
# ]
# 注意:如果不存在可能的有效操作,请返回一个空列表 []。
#me
class Solution0(object):
def generatePossibleNextMoves(self, s):
lastsList = []
for i in range(len(s)):
if s[i:i+2] == ‘++‘:
news = s[:i]+‘--‘+s[i+2:]
lastsList.append(news)
return lastsList
30.思路:直述题意(列表相加)
# 给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
# 你可以返回满足此条件的任何数组作为答案。
# 示例:
# 输入:[3,1,2,4]
# 输出:[2,4,3,1]
# 输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
#列表有+无-,集合有-无+
#me
class Solution(object):
def sortArrayByParity(self, A):
jiShu = [i for i in A if i%2==1]
ouShu = [j for j in A if j%2==0]
return ouShu+jiShu
31.思路:直述题意(集合子集)
#给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。
# 示例:
# 输入: ["Hello", "Alaska", "Dad", "Peace"]
# 输出: ["Alaska", "Dad"]
# 注意:
# 你可以重复使用键盘上同一字符。
# 你可以假设输入的字符串将只包含字母。
#me
#集合<表示包含,<=表示子集
class Solution0(object):
def findWords(self, words):
wordLine0 = [‘Q‘,‘W‘,‘E‘,‘R‘,‘T‘,‘Y‘,‘U‘,‘I‘,‘O‘,‘P‘,‘q‘,‘w‘,‘e‘,‘r‘,‘t‘,‘y‘,‘u‘,‘i‘,‘o‘,‘p‘]
wordLine1 = [‘A‘,‘S‘,‘D‘,‘F‘,‘G‘,‘H‘,‘J‘,‘K‘,‘L‘,‘a‘,‘s‘,‘d‘,‘f‘,‘g‘,‘h‘,‘j‘,‘k‘,‘l‘]
wordLine2 = [‘Z‘,‘X‘,‘C‘,‘V‘,‘B‘,‘N‘,‘M‘,‘z‘,‘x‘,‘c‘,‘v‘,‘b‘,‘n‘,‘m‘]
results = []
for word in words:
wordList = [str(i) for i in word]
if set(wordList)<=set(wordLine0) or set(wordList)<=set(wordLine1) or set(wordList)<=set(wordLine2):
results.append(word)
return results
32.思路:直述题意
# 给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。
# 注意:
# 给定的整数保证在32位带符号整数的范围内。
# 你可以假定二进制数不包含前导零位。
# 示例 1:
# 输入: 5
# 输出: 2
# 解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。
# 示例 2:
# 输入: 1
# 输出: 0
# 解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。
#思路:找到一个二进制位数与num相同但每一位都为1的数,然后用这个数 减去 num。例如 0b111-0b101=0b10,7-5=2,这里7就是我们要找的数
#other
class Solution(object):
def findComplement(self, num):
i = 1
# 最高位为1,其余为0,刚好比num大然后用这个数减去1就是我们要找的数
while num >= i:
i = i << 1 # 每次向左移1位 i=0b1000
return i-1-num
33.思路:集合交集(&)
# 给定两个数组,编写一个函数来计算它们的交集。
# 示例 1:
# 输入: nums1 = [1,2,2,1], nums2 = [2,2]
# 输出: [2]
# 示例 2:
# 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
# 输出: [9,4]
# 说明:
# 输出结果中的每个元素一定是唯一的。
# 我们可以不考虑输出结果的顺序。
#me
class Solution0(object):
def intersection(self, nums1, nums2):
return list(set([i for i in nums1 if i in nums2]))
#other
class Solution1(object):
def intersection(self, nums1, nums2):
return list(set(nums1) & set(nums2))
34.思路:排序,前n个元素相加
# 楼下水果店正在促销,你打算买些苹果,arr[i] 表示第 i 个苹果的单位重量。
# 你有一个购物袋,最多可以装 5000 单位重量的东西,算一算,最多可以往购物袋里装入多少苹果。
# 示例 1:
# 输入:arr = [100,200,150,1000]
# 输出:4
# 解释:所有 4 个苹果都可以装进去,因为它们的重量之和为 1450。
# 示例 2:
# 输入:arr = [900,950,800,1000,700,800]
# 输出:5
# 解释:6 个苹果的总重量超过了 5000,所以我们只能从中任选 5
#me
class Solution0(object):
def maxNumberOfApples(self, arr):
newarr = sorted(arr)
sum = 0
for ID,num in enumerate(newarr):
sum +=num
if sum > 5000:
return ID
return len(arr)
#other
class Solution1(object):
def maxNumberOfApples(self, arr):
if arr == []:
return 0
arr, bag_size, count = sorted(arr), 5000, 0
for apple in arr:
bag_size -= apple
if bag_size <= 0:
return count
count += 1
return count
*35.思路:数学推导
# 给定一个整数数组 A,对于每个整数 A[i],我们可以选择任意 x 满足 -K <= x <= K,并将 x 加到 A[i] 中。
# 在此过程之后,我们得到一些数组 B。
# 返回 B 的最大值和 B 的最小值之间可能存在的最小差值。
# 示例 1:
# 输入:A = [1], K = 0
# 输出:0
# 解释:B = [1]
# 示例 2:
# 输入:A = [0,10], K = 2
# 输出:6
# 解释:B = [2,8]
# 示例 3:
# 输入:A = [1,3,6], K = 3
# 输出:0
# 解释:B = [3,3,3] 或 B = [4,4,4]
#other
class Solution(object):
def smallestRangeI(self, A, K):
#数学推导问题
return max(0,(max(A) - min(A) -2*K))
36.思路:直述题意(集合)
# 给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。
# 如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。
# 示例 1:
# 输入:arr = [1,2,2,1,1,3]
# 输出:true
# 解释:在该数组中,1 出现了 3 次,2 出现了 2 次,3 只出现了 1 次。没有两个数的出现次数相同。
# 示例 2:
# 输入:arr = [1,2]
# 输出:false
# 示例 3:
# 输入:arr = [-3,0,1,-3,1,1,1,-3,10,0]
# 输出:true
#me
class Solution(object):
def uniqueOccurrences(self, arr):
arrset = set(arr)
allnum = []
for i in arrset:
num=0
for j in arr:
if i==j:
num+=1
allnum.append(num)
if len(set(allnum)) == len(allnum):
return True
else:
return False
37.思路:直述题意(两次便利或列表推导式)
# 给定一个矩阵 A, 返回 A 的转置矩阵。
# 矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。
# 示例 1:
# 输入:[[1,2,3],[4,5,6],[7,8,9]]
# 输出:[[1,4,7],[2,5,8],[3,6,9]]
# 示例 2:
# 输入:[[1,2,3],[4,5,6]]
# 输出:[[1,4],[2,5],[3,6]]
#me
class Solution0(object):
def transpose(self, A):
result = []
for i in range(len(A[0])):
mid = []
for j in range(len(A)):
mid.append(A[j][i])
result.append(mid)
return result
#other
class Solution1(object):
def transpose(self, A):
return [[i[j] for i in A] for j in range(len(A[0]))]
38.思路:直述题意(list.count())
# 在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次。
# 返回重复了 N 次的那个元素。
# 示例 1:
# 输入:[1,2,3,3]
# 输出:3
# 示例 2:
# 输入:[2,1,2,5,3,2]
# 输出:2
# 示例 3:
# 输入:[5,1,5,2,5,3,5,4]
# 输出:5
#me
class Solution(object):
def repeatedNTimes(self, A):
for i in set(A):
if A.count(i)==len(A)//2:
return i
39.思路:直述题意
# 给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
# 对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。
# 你可以返回任何满足上述条件的数组作为答案。
# 示例:
# 输入:[4,2,5,7]
# 输出:[4,5,2,7]
# 解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。
#me
class Solution0(object):
def sortArrayByParityII(self, A):
result = []
jiShu = [i for i in A if i % 2==1]
ouShu = [j for j in A if j % 2==0]
for k in range(len(jiShu)):
result.append(ouShu[k])
result.append(jiShu[k])
return result
#other
class Solution:
def sortArrayByParityII(self, A):
ia = [i for i in A if not(i % 2)]
ja = [i for i in A if i % 2]
return [i for n in zip(ia, ja) for i in n]
40.思路:直述题意
# 给你一个不同学生的分数列表,请按 学生的 id 顺序 返回每个学生 最高的五科 成绩的 平均分。
# 对于每条 items[i] 记录, items[i][0] 为学生的 id,items[i][1] 为学生的分数。平均分请采用整数除法计算。
# 示例:
# 输入:[[1,91],[1,92],[2,93],[2,97],[1,60],[2,77],[1,65],[1,87],[1,100],[2,100],[2,76]]
# 输出:[[1,87],[2,88]]
# 解释:
# id = 1 的学生平均分为 87。
# id = 2 的学生平均分为 88.6。但由于整数除法的缘故,平均分会被转换为 88。
# 来源:力扣(LeetCode)
# 链接:https://leetcode-cn.com/problems/high-five
# 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
#me
class Solution0(object):
def highFive(self, items):
allresult = []
ids = max([i[0] for i in items])
for id_ in range(ids):
mid = []
for item in items:
if item[0] == id_+1:
mid.append(item[1])
allresult.append(mid)
avgresults = []
for result in allresult:
sortresult = sorted(result)
avgresult = sum(sortresult[-5:])/5
avgresults.append(avgresult)
lastresult = zip(range(1,ids+1),avgresults)
return lastresult
#other
class Solution1(object):
def highFive(self, items):
id_list = list(set([i for i,j in items]))
res = []
for id_1 in id_list:
score_arr = []
for ids,scores in items:
if id_1 == ids:
score_arr.append(scores)
sums = sum(sorted(score_arr,reverse=True)[:5])
res.append([id_1,int(sums/5)])
return res
以上是关于Leetcode简单题21~40的主要内容,如果未能解决你的问题,请参考以下文章