20220630Leetcode-03
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二十、剑指 Offer 31. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。
提示:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列。
class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
stack=[]
i=0
for p in pushed:
stack.append(p)
while stack and stack[-1]==popped[i]:
stack.pop()
i=i+1
return not stack
stack
class Stack(object):
def __init__(self):
self.stack = []
def push(self, data):
"""
进栈函数
"""
self.stack.append(data)
def pop(self):
"""
出栈函数,
"""
return self.stack.pop()
def gettop(self):
"""
取栈顶
"""
return self.stack[-1]
二十一、剑指 Offer 30. 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
提示:
各函数的调用总次数不超过 20000 次
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class MinStack:
def __init__(self):
self.A, self.B = [], []
def push(self, x: int) -> None:
self.A.append(x)
if not self.B or self.B[-1] >= x:
self.B.append(x)
def pop(self) -> None:
if self.A.pop() == self.B[-1]:
self.B.pop()
def top(self) -> int:
return self.A[-1]
def min(self) -> int:
return self.B[-1]
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()
二十二、剑指 Offer 15. 二进制中1的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。
提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用 二进制补码 记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。
示例 1:
输入:n = 11 (控制台输入 00000000000000000000000000001011)
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。
示例 2:
输入:n = 128 (控制台输入 00000000000000000000000010000000)
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
示例 3:
输入:n = 4294967293 (控制台输入 11111111111111111111111111111101,部分语言中 n = -3)
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。
提示:
输入必须是长度为 32 的 二进制串 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/er-jin-zhi-zhong-1de-ge-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
若 n & 1 = 0,为0。
若 n & 1 = 1,为1。
class Solution:
def hammingWeight(self, n: int) -> int:
res = 0
while n:
res += n & 1
n >>= 1// 将二进制数字n无符号右移一位
return res
二十三、剑指 Offer 58 - I. 翻转单词顺序
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
class Solution:
def reverseWords(self, s: str) -> str:
s = s.strip() # 删除首尾空格
strs = s.split() # 分割字符串
strs.reverse() # 翻转单词列表
return ' '.join(strs) # 拼接为字符串并返回
结论:split()的时候,多个空格当成一个空格;split(’ ')的时候,多个空格都要分割,每个空格分割出来空。
python中split()和split(’ ')的区别
(https://www.cnblogs.com/python-coder/p/10073329.html)
用split(" ")测试:
s1 = "we are family"#中间一个空格
s2 = "we are family"#中间两个空格
s3 = "we are family"#中间三个空格
s4 = "we are family"#中间四个空格
s1 = s1.split(" ")
s2 = s2.split(" ")
s3 = s3.split(" ")
s4 = s4.split(" ")
print(s1)#['we', 'are', 'family']
print(s2)#['we', '', 'are', '', 'family']
print(s3)#['we', '', '', 'are', '', '', 'family']
print(s4)#['we', '', '', '', 'are', '', '', '', 'family']
用split()测试:
s1 = "we are family"#中间一个空格
s2 = "we are family"#中间两个空格
s3 = "we are family"#中间三个空格
s4 = "we are family"#中间四个空格
s1 = s1.split()
s2 = s2.split()
s3 = s3.split()
s4 = s4.split()
print(s1)#['we', 'are', 'family']
print(s2)#['we', 'are', 'family']
print(s3)#['we', 'are', 'family']
print(s4)#['we', 'are', 'family']
python strip():用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
str = "00000003210Runoob01230000000";
print str.strip( '0' ); # 去除首尾字符 0
//3210Runoob0123
str2 = " Runoob "; # 去除首尾空格
print str2.strip();
//Runoob
str = "123abcrunoob321"
print (str.strip( '12' )) # 字符序列为 12
//3abcrunoob3
Python List reverse()方法:反向列表中元素
aList = [123, 'xyz', 'zara', 'abc', 'xyz']
aList.reverse()
print "List : ", aList
//List : ['xyz', 'abc', 'zara', 'xyz', 123]
二十四、剑指 Offer 58 - II. 左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”
示例 2:
输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”
限制:1 <= k < s.length <= 10000
//列表遍历拼接
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
//取余方法
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
res = ""
for i in range(n, n + len(s)):
res += s[i % len(s)]
return res
//切片函数
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
m = []
m=s
m = m+m[0:n]
return m[n:]
二十五、剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:1 <= 数组长度 <= 50000
本题常见的三种解法:
- 哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为O(N)。
- 数组排序法: 将数组 nums 排序,数组中点的元素 一定为众数。
- 摩尔投票法: 核心理念为 票数正负抵消
。此方法时间和空间复杂度分别为 O(N)O(N) 和 O(1)O(1) ,为本题的最佳解法。
摩尔投票法
摩尔投票法找的不是众数,而是占一半以上的数。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
votes = 0
for num in nums:
if votes == 0: x = num
votes += 1 if num == x else -1
return x
找众数的方法:
哈希表
哈希映射(HashMap)来存储每个元素以及出现的次数。对于哈希映射中的每个键值对,键表示一个元素,值表示该元素出现的次数。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
counts = collections.Counter(nums)
return max(counts.keys(), key=counts.get)
排序
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
return nums[len(nums) // 2]
作者:wu-xian-sen-2
链接:https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/solution/python3-ji-chu-pai-xu-suan-fa-zong-jie-by-wu-xian-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
基础排序算法总结
交换类:冒泡排序、快速排序
选择类:简单选择排序、堆排序
插入类:直接插入排序、shell 排序
归并类:归并排序
冒泡排序
class Solution1:
@staticmethod
def swap(nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
def bubble_sort(self, nums):
for i in range(1, len(nums)): # 控制比较趟数,最多比较 len(nums) - 1趟
flag = False # 比较当前趟是否发生交换,没有则已经排序好了
for j in range(0, len(nums) - i):
if nums[j] > nums[j + 1]:
flag = True
self.swap(nums, j, j + 1)
if not flag: return nums
return nums
def getLeastNumbers(self, arr, k: int):
if not arr or k <= 0: return []
if len(arr) <= k: return arr
return self.bubble_sort(arr)[:k]
二十六、剑指 Offer 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
限制:
数组长度为 5
数组的数取值为 [0, 13]
class Solution:
def isStraight(self, nums: List[int]) -> bool:
repeat = set()
ma, mi = 0, 14
for num in nums:
if num == 0:
continue
ma = max(ma, num)
mi = min(mi, num)
if num in repeat:
return False
repeat.add(num)
return ma - mi < 5