题目描述1:58.左旋转字符串 难度:简单
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
解题思路:
字符串切片
列表遍历拼接
字符串遍历拼接
Python代码:
class Solution: def reverseLeftWords(self, s: str, n: int) -> str: return s[n:] + s[:n]class Solution: def reverseLeftWords(self, s: str, n: int) -> str: res = [] for i in range(n, len(s)): res.append(s[i]) for i in range(n): res.append(s[i]) return ''.join(res)class Solution: def reverseLeftWords(self, s: str, n: int) -> str: res = "" for i in range(n, len(s)): res += s[i] for i in range(n): res += s[i] return res
题目描述2:59.滑动窗口的最大值 难度:简单
给定一个数组 nums
和滑动窗口的大小 k
,请找出所有滑动窗口里的最大值。
解题思路:
无
Python代码:
class Solution: def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: if not nums: return [] # res = [] # length = len(nums) # i, j = 0, k # while j <= length: # res.append(max(nums[i:j])) # i += 1 # j += 1 # return res n = len(nums) return [max(nums[i:i + k]) for i in range(n - k + 1)]
题目描述3:59.队列的最大值 难度:中等
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1:
输入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
示例 2:
输入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
输出: [null,-1,-1]
解题思路:
无
Python代码:
class MaxQueue: def __init__(self): self.A = [] self.B = [] def max_value(self) -> int: if not self.B: return -1 else: return self.B[0] def push_back(self, value: int) -> None: self.A.append(value) if not self.B: self.B.append(value) else: while self.B and self.B[-1] < value: self.B.pop() self.B.append(value) def pop_front(self) -> int: if not self.A: return -1 else: temp = self.A.pop(0) if temp == self.B[0]: self.B.pop(0) return temp# Your MaxQueue object will be instantiated and called as such:# obj = MaxQueue()# param_1 = obj.max_value()# obj.push_back(value)# param_3 = obj.pop_front()
题目描述4:60.n个骰子的点数 难度:中等
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
示例 1:
输入: 1
输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
示例 2:
输入: 2
输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778
解题思路:
我们的思路是计算所有骰子点数出现的次数,然后除以总的可能数即可,总的可能性容易求出,为 6 ^ n,问题的关键在于求解每一个点数出现的次数。
首先很明显只有一个骰子的时候,1,2,3,4,5,6出现的次数都为1。
那么如果两个骰子,出现次数为7的话,有多少种呢?应该是6种,分别是:
那么如果两个骰子,出现次数为8的话,有多少种呢?应该是5种,分别是:
我们发现,我们只需要用一个数组cnts,cnts[i] 表示掷出i的次数,那么cnts[i] 就等于前面六个相加,或者前面五个相加,或者。
为了简单起见,我们从后往前遍历,这样我们的逻辑可以统一为 cnts[i] 就等于前面六个cnts[j]相加,其中j等于i - 1, i - 2, i - 3, i - 4, i - 5, i - 6。
Python代码:
class Solution: def dicesProbability(self, n: int) -> List[float]: count = 6**n dp = [[0 for _ in range(6*n+1)] for _ in range(n+1)] for i in range(1,7): dp[1][i] = 1 for i in range(2,n+1): for j in range(i,6*i+1): for k in range(1,7): #第i个骰子可能出现的数字 if j - k >= i-1: #i是第i个骰子最小值,i-1是前i-1个骰子最小值 dp[i][j] += dp[i-1][j-k] return [x/count for x in dp[n][n:6*n+1]] #列表不能整体做除法,需要遍历每个元素
题目描述5:61.扑克牌中的顺子 难度:简单
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1:
输入: [1,2,3,4,5]
输出: True
示例 2:
输入: [0,0,1,2,5]
输出: True
解题思路:
如果重复,肯定错误。如果不存在0,则最大值最小值之差必定为4 其他情况,最大值最小值之差小于5即可。
Python代码:
class Solution: def isStraight(self, nums: List[int]) -> bool: repeat = set() maxnum,minnum = 0,14 for num in nums: if num == 0:continue #跳过大小王 maxnum = max(maxnum,num) #更新最大牌 minnum = min(minnum,num) #更新最小牌 if num in repeat:return False #若有重复,提前返回false repeat.add(num) #添加牌至set return maxnum - minnum < 5
题目描述6:62.圆圈中最后剩下的数字 难度:简单
0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
示例 1:
输入: n = 5, m = 3
输出: 3
示例 2:
输入: n = 10, m = 17
输出: 2
解题思路:
Python代码:
class Solution: def lastRemaining(self, n: int, m: int) -> int: f = 0 for i in range(2,n+1): f = (f+m)%i return f
题目描述7:63.股票的最大利润 难度:简单
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
解题思路:
无
Python代码:
class Solution: def maxProfit(self, prices: List[int]) -> int: if len(prices) < 1:return 0 minprice = prices[0] maxprofit = 0 for i in prices: minprice = min(minprice,i) maxprofit = max(maxprofit,(i - minprice)) return maxprofit
题目描述8:64.求1+2+...+n 难度:中等
求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例 1:
输入: n = 3
输出: 6
示例 2:
输入: n = 9
输出: 45
解题思路:
递归
Python代码:
class Solution: def __init__(self): self.result = 0 def sumNums(self, n: int) -> int: n > 1 and self.sumNums(n-1) self.result += n return self.result
题目描述9:65.不用加减乘除做加法 难度:简单
写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。
示例:
输入: a = 1, b = 1
输出: 2
解题思路:
算法思想描述:不用加减乘除法做加法,需要做的就是将两个数a、b先按位异或得到a^b,将a^b视为a与b的不考虑进位的按位加;
然后按位与得到a&b并左移,将a&b<<1视为a与b的每一位在相加之后的进位;
将a^b与a&b<<1再按照步骤1、2相加,直到b为0;
对于python,负数的处理有些特殊,负数的补码是a&0xffffffff,在计算之后,返回数值时,python能够表达的最大整数是0x7fffffff,若计算出的结果大于0x7fffffff,表示是一个负数,此时应该将答案a按照~(a^x)进行处理,才是返回的负数数值。
Python代码:
class Solution: def add(self, a: int, b: int) -> int: while b: result = (a ^ b) & 0xffffffff carry = ((a & b) << 1) & 0xffffffff a = result b = carry if a <= 0x7fffffff: #断a为正数还是负数,正数则直接返回。负数则返回-((a - 1) ^ 0xffffffff) result = a else: result = -((a - 1) ^ 0xffffffff) return result
题目描述10:66.构建乘积数组 难度:中等
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
示例:
输入: [1,2,3,4,5]
输出: [120,60,40,30,24]
解题思路:
Python代码:
class Solution: def constructArr(self, a: List[int]) -> List[int]: b,temp = [1]*len(a),1 for i in range(1,len(a)): b[i] = b[i-1]*a[i-1] #下三角形 for i in range(len(a)-2,-1,-1): temp *= a[i+1] b[i] *= temp #下三角形*上三角形 return b
题目描述11:67.把字符串转换成整数 难度:中等
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。
示例 1:
输入: "42"
输出: 42
示例 2:
输入: " -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
示例 4:
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
因此无法执行有效的转换。
示例 5:
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
因此返回 INT_MIN (−231) 。
解题思路:
Python代码:
class Solution: def strToInt(self, str: str) -> int: string = str.strip() if not string:return 0 res,i,sign = 0,1,1 int_max,int_min,boundary = 2**31-1,-2**31,2**31//10 if string[0] == '-': sign = -1 elif string[0] != '+':i=0 for c in string[i:]: if not '0' <= c <= '9':break if res > boundary or res == boundary and c > '7':return int_max if sign == 1 else int_min res = 10*res + ord(c) - ord('0') return sign*res
题目描述12:68.二叉搜索树的最近公共祖先 难度:简单
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
解题思路:
Python代码:
#方法1codeclass Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': if root.val < p.val and root.val < q.val: return self.lowestCommonAncestor(root.right,p,q) if root.val > p.val and root.val > q.val: return self.lowestCommonAncestor(root.left,p,q) return root #方法2code class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': while root: if root.val < p.val and root.val < q.val: root = root.right elif root.val > p.val and root.val > q.val: root = root.left else: break return root
题目描述13:68.二叉树的最近公共祖先 难度:中等
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
解题思路:
Python代码:
#方法1codeclass Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': if not root: return None if root == p or root == q: return root left = self.lowestCommonAncestor(root.left,p,q) right = self.lowestCommonAncestor(root.right,p,q) if not left: return right if not right: return left if left and right: #p和q在异侧 return root return None