.index : 查找索引
A[::] : 对数组进行切片并从前往后取值
A[::-1] : 对数组进行切片并从后往前取值
递归调用:函数在运行时调用自己,可求解两数之和
set() : 创建集合(集合内不会有重复的元素!!!可用于判断重复字符)但是无序的,无下标!!
可通过原列表和创建set后的长度是否一致来判断有无重复字符。
pairwise() : 从左到右输出步长为2的数组对
enumerate() : 同时获得索引和值
stack : 栈, 先入后出。 stack.pop() 入 stack.append()出
replace :将字符串中的某一元素替换成指定元素,但不会改变原来字符串的内容。 str.replace('old', 'new', count])
剔除指定元素,并返回与指定元素不同值的数量和数组:
(第一次完完整整自己敲代码没报错并且输出居然是对的!!
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
k = 0
for i in range(len(nums)):
if nums[i] != val:
nums[k] = nums[i]
k += 1
return k
9.27 刷的第二题也是一次通过!!纪念一下:
(虽然不是最优解,看了解答代码还能再简化,继续努力!!
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if len(haystack) < len(needle): return -1
if haystack == needle : return 0
for i in range(len(haystack)-len(needle)+1):
if haystack[i:i+len(needle)] == needle:
return i
i += 1
if i == len(haystack)-len(needle)+1 and haystack[i:] != needle:
return -1
今天学二分法:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
解析:返回nums中的第一个(最左边)大于或等于target的数的下标。如果所有数都小于target,返回nums的长度。
def lower_bound(nums: List[int], target: int) -> int:
left, right = 0, len(nums) -1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1 # 范围缩小到 [mid+1, right]
else:
right = mid - 1 # 范围缩小到 [left, mid-1]
return left
## 相当于循环不变量:
## nums[left - 1] < target
## nums[right + 1] >= target
s.rstrip() : 去除最右边的空格字符
s.split("") : 以“”为间隔进行切片, 可用于计算字符串中单词数!
用for循环倒序读字符串,可让i=len(s)-1
检查进位问题:
def plusOne(self, digits: List[int]) -> List[int]:
cur = 1
for i in range(len(digits) - 1, -1, -1):
cur += digits[i]
digits[i] = cur % 10
cur //= 10
return digits if not cur else [cur] + digits
# 如果cur是none就返回digits,否则返回一个新列表,第一个元素是[cur],后面是digits
int(a,b) : a表示传入的字符串,b表示输出的进制数,可用于非十进制的加法计算
二叉树:
# 递归
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
# 前序递归
return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
# # 中序递归
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
# # 后序递归
return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]
递归法输出二叉树的深度:
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if root is None: return 0
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
生成杨辉三角:
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
a = [[1] * (i+1) for i in range(numRows)]
for i in range (2,numRows):
for j in range(1,i):
a[i][j] = a[i-1][j-1] + a[i-1][j]
return a
买股票问题:如果第i天卖出股票,则最大利润为(该天的股价-前面天数中最小的股价),然后与已知的最大利润比较,如果大于则更新当前最大利润的值。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
minprice = float('inf')
maxpro = 0
for price in prices:
minprice = min(minprice, price)
maxpro = max(maxpro, price - minprice)
return maxpro
异或运算:相同二进制位为0,不同为1:0 ^ x = x; x ^ x = 0. 可用于消除出现了两次的元素
Excel表:要转成26进制, A的ASCII值为65
class Solution:
def convertToTitle(self, columnNumber: int) -> str:
res = ""
while columnNumber:
columnNumber -= 1
columnNumber, y = divmod(columnNumber, 26)
res = chr(y+65) + res
return res
pandas.merge(left, right, how: str = 'inner', on=None, left_on=None, right_on=None, left_index: bool = False, right_index: bool = False, sort: bool = False, suffixes='_x', '_y', copy: bool = True, indicator: bool = False, validate=None) 用于合并两个DataFrame
DataFrame[' '].value_counts() : 统计DataFrame中某一标签下的数量
DataFrame.loc(x,y): 取DataFrame的x行y列
bin(x): 得到整数x的二进制数
<< , >>: 二进制数的位运算,分别为对二进制数进行左移和右移
& 符号,x & y ,会将两个十进制数在二进制下进行与运算
| 符号,x | y ,会将两个十进制数在二进制下进行或运算
^ 符号,x ^ y ,会将两个十进制数在二进制下进行异或运算
<< 符号,x << y 左移操作,最右边用 0 填充
>> 符号,x >> y 右移操作,最左边用 0 填充
~ 符号,~x ,按位取反操作,将 x 在二进制下的每一位取反
shift(1): 将DataFrame中所有元素下移一行
dummy_head = ListNode(next=head) #添加一个虚拟节点
同构字符串:如果 s
中的字符可以按某种映射关系替换得到 t
,那么这两个字符串是同构的。
解题思路:找到两个子母中不同字符从左到右的的index 列表是否完全一致
class Solution:
def isIsomorphic(self, s: str, t: str) -> bool:
return all(s.index(s[i]) == t.index(t[i]) for i in range(len(s)))
递归法反转链表思路: 定义recur(cur,pre)函数,cur记录当前节点,pre指向前节点(所以开始需要用None给一个空节点), 终止条件是cur为空,res来记录反转后的链表。
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
def recur(cur,pre):
if not cur: return res
while cur:
res = recur(cur.next, cur)
cur.next = pre
return res
return recur(head, None)
完满二叉树:如果有孩子,一定是两个
完全二叉树:除最后一层外所有节点都被填充,且所有节点向左对齐
完美二叉树:所有节点都有两个孩子
汇总区间:返回恰好覆盖数组中所有数字的最小有序区间范围列表。利用双指针求解,指针移动策略是相邻元素之间差1。
2的次幂在二进制下只有首位是1其余位都是0
判断字母异位:字符串不能用set!!可以用哈希表,统计a字符串中每个字母出现的次数(操作为+1),再统计b字符串中每个字母出现的次数(操作为-1),最后若为0则输出True。
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
from collections import defaultdict
if len(s) != len(t):
return False
dic = defacultdict(int)
for x in s:
dic[x] += 1
for x in t:
dic[x] -= 1
for val in dic.values():
if val != 0:
return False
return True
各位相加:给定一个非负整数 num
,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。列举0-30的情况可以发现,0特例,1-9输出为数本身,10-18输出与1-9相同,19-27输出也与1-9相同,可见9个数一循环。
class Solution:
def addDigits(self, num: int) -> int:
return 9 if (num % 9 == 0 ) and (num != 0) else num % 9
对于二进制数,可以直接用.count("1")来统计位为1的个数。
反转字符串中的元音字母:也用双指针法,注意while和if的条件。
class Solution:
def reverseVowels(self, s: str) -> str:
a = set('aeiouAEIOU')
l, r = 0, len(s) - 1
s = list(s)
while l < r:
if s[l] in a and s[r] in a:
s[l], s[r] = s[r], s[l]
l += 1
r -= 1
if s[l] not in a:
l += 1
if s[r] not in a:
r -= 1
return ''.join(s)
.sort():对列表进行排序,默认是升序,用reverse=True可改为降序。
判断有效的完全平方数:二分查找法
class Solution:
def isPerfectSquare(self, num: int) -> bool:
l, r = 1, num
while l < r:
mid = (l + r) // 2
if mid * mid < num:
l = mid + 1
else:
r = mid
return l * l == num
Counter():跟踪值出现的次数,以字典的键值对形式存储,元素作为key,其计数作为value。
Counter类的创建
>>> c = Counter() # 创建一个空的Counter类
>>> c = Counter('gallahad') # 从一个可iterable对象(list、tuple、dict、字符串等)创建
>>> c = Counter({'a': 4, 'b': 2}) # 从一个字典对象创建
>>> c = Counter(a=4, b=2) # 从一组键值对创建
Counter("aabcdd")
Counter("a") --> 2
重复的子字符串:如果一个字符串s可以通过他的一个子串重复得到,说明将这个字符串重复一遍(s+s),去掉头尾后依然可以找到s自己;如果不能通过子串重复的到,那么s+s中找不到自己。
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
return s in (s + s)[1:-1]
二进制手表:(这题也泰难了,居然属于简单题吗。。。)
为了方便计算,分别设置了小时数组和分钟数组
递归的四个参数分别代表:剩余需要点亮的灯数量,从索引index开始往后点亮灯,当前小时数,当前分钟数每次进入递归后,先判断当前小时数和分钟数是否符合要求,不符合直接return
for循环枚举点亮灯的情况,从index枚举到10,每次枚举,减少一个需要点亮的灯数量num - 1
从当前已点亮的灯后面选取下一个要点亮的灯 i + 1在hour中增加当前点亮灯的小时数,如果i大于3,当前灯是分钟灯而不是小时灯,则加上0个小时在minute中增加当前点亮灯的分钟数,如果i没有大于3,当前灯是小时灯而不是分钟灯,则加上0分钟当剩余需要点亮的灯数量为0的时候,已枚举完一种情况,根据题目要求的格式加到res列表中返回res
class Solution:
def readBinaryWatch(self, turnedOn: int) -> List[str]:
hours = [1, 2, 4, 8, 0, 0, 0, 0, 0, 0]
minutes = [0, 0, 0, 0, 1, 2, 4, 8, 16, 32]
res = []
def backtrack(num, index, hour, minute):
if hour > 11 or minute >59:
return
if num == 0:
res.append('%d:%02d'%(hour,minute))
return
for i in range(index, 10):
backtrack(num - 1, i + 1, hour + hours[i], minute + minutes[i])
backtrack(turnedOn, 0, 0, 0)
return res
数字转化为十六进制数:
CONV = "0123456789abcdef"
class Solution:
def toHex(self, num: int) -> str:
ans = []
for _ in range(8):
ans.append(num%16)
num //= 16
if not num:
break
return "".join(CONV[n] for n in ans[::-1])
构建回文串:如果回文串长度为偶数,则每个字符都应该出现偶数次;如果长度为奇数,那么只有中间字符出现奇数次,其他字符出现偶数次。
class Solution:
def longestPalindrome(self, s: str) -> int:
counter = collections.defaultdict(int)
res, odd = 0,0
for x in s:
counter[x] += 1
for count in counter.values():
amp = count % 2
res += count - amp
if amp == 1 : odd = 1
return res + odd
s.lstrip(' ') s.rstrip(' ') s.strip(' '):分别为去除字符串左边、右边、全部的‘ ’ 字符
构造符合要求的矩形:长度 L
和宽度 W
之间的差距应当尽可能小, L>=W,L*W=area
翻译一下,其实就是求area最接近开根的值L。
class Solution:
def constructRectangle(self, area: int) -> List[int]:
for i in range(int(sqrt(area)),0,-1):
if not area % i : ## 也可以写成 if area % i == 0
return [area // i, i]
通常一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素,且要求 O(n) 的时间复杂度,用单调栈。以下为寻找右边第一个比自己大的元素,并返回该元素,若不存在返回-1。
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
idx = {x: i for i, x in enumerate(nums1)}
ans = [-1] * len(nums1)
st = []
for x in reversed(nums2):
while st and x >= st[-1]:
st.pop()
if st and x in idx:
ans[idx[x]] = st[-1]
st.append(x)
return ans
二叉搜索树中的众数:中序遍历!!常用
Class Solution:
# 中序遍历
def inOrder(self, root:TreeNode, lst):
if root is None:
return None
self.inOrder(root.left, lst)
lst.append(root.val)
self.inOrder(root.right, lst)
def findMode(self, root:Optional[TreeNode]) -> List[int]:
lst = [] # 根列表
self.inOrder(root, lst)
cnt = 1 # 记录当前次数
maxcnt = 1 # 记录最大次数
pre = lst[0] # 记录前一个元素
res = [lst[0]] # 保存结果
for i in range(1, len(lst)):
if pre == lst[i]: # 如果前一个元素和当前元素相同,计数器加一
cnt += 1
elif:
cnt = 1
if cnt == maxcnt: # 如果当前元素的计数器等于目前的最大次数,把该元素加入res
res.append(lst[i])
if cnt > maxcnt: # 如果当前元素的计数器大于目前最大次数,res更新为当前元素
maxcnt = cnt
res = [lst[i]]
pre = lst[i]
return res
判定完美数:又又又一次写的代码超时了。。。为什么别人的脑子这么好用www
完美数: ∗
且 p 和 2p−1 都为质数
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
ans = 1
x = 2
y = 2
while y > 1:
if num % x == 0:
ans += x
x += 1
y = num // x
if ans == num:
return True
if ans != num:
return False
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
def isPrime(x):
for j in range(2, x//2):
if not x % j:
return False
return x > 1
p = 1
while not num //2 :
num //= 2
p += 1
return num + 1 == pow(2,p) and isPrime(x) and isPrime(p)
Dataframe的一些操作数:
dt.sort_values(by='colunms_name') 对指定列按照升序排列
dt.groupby(['colunms_name)']) 按照指定列对数据分组
dt['colunms__name'].first().reset_index() first 函数返回指定列每个分组中的第一个非缺失值,reset重置索引