1. 数组中重复的数字
长度n,数字0-n-1
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param numbers int整型一维数组
# @return int整型
#
class Solution:
def duplicate(self , numbers: List[int]) -> int:
n = len(numbers)
for i in range(n):
num = numbers[i]
while num != i:
if num < 0 or num > n-1:
return -1
elif numbers[num] == num:
return num
numbers[i],numbers[num] = numbers[num],numbers[i]
num = numbers[i]
return -1
引申:不修改数组,找出重复的数字
长度n+1的数组里,所有数字都在1-n范围内注意这里与上面的数字范围其实不同,只有数字区间比长度小1的时候可以这么做,上一题数字区间与长度是一样长的
方法1:用o(n)辅助空间,时间复杂度o(n)
方法2:不用辅助空间,用二分法count数字数量,时间复杂度o(nlog(n))
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param numbers int整型一维数组
# @return int整型
#
class Solution:
def duplicate(self, numbers: list[int]) -> int:
n = len(numbers)
if n < 2:
return -1
l,r = 0,n-1
while l < r-1:
mid = (l + r) // 2
numCnt = 0
for num in numbers:
if num <= mid:
numCnt += 1
if numCnt > mid-l+1:
r = mid
else:
l = mid+1
lNumCnt,rNumCnt = 0,0
for num in numbers:
if num == numbers[l]:
lNumCnt += 1
elif num == numbers[r]:
rNumCnt += 1
if lNumCnt > 1:
return numbers[l]
if rNumCnt > 1:
return numbers[r]
return -1
2. 二维数组中的查找
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param target int整型
# @param array int整型二维数组
# @return bool布尔型
#
class Solution:
def Find(self , target: int, array: List[List[int]]) -> bool:
if len(array) == 0 or len(array[0]) == 0:
return False
m,n = len(array),len(array[0])
# select the number on right up corner
i,j = 0,n-1
while array[i][j] != target:
if array[i][j] < target:
i += 1
else:
j -= 1
if i < 0 or i > m-1 or j < 0 or j > n-1:
return False
return True
3. 替换空格
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param s string字符串
# @return string字符串
#
class Solution:
def replaceSpace(self , s: str) -> str:
# step1: 统计空格数量
n = len(s)
spaceCnt = 0
for i in range(n):
if s[i] == " ":
spaceCnt += 1
# 注意这里增加的数量的2倍空格,空格本身就有位置
s = s + " " * spaceCnt * 2
# python字符串无法修改,改成list修改
s = list(s)
j = len(s) - 1
for i in range(n-1,-1,-1):
if s[i] == " ":
s[j],s[j-1],s[j-2] = "0","2","%"
j -= 3
else:
s[j] = s[i]
j -= 1
print("".join(s))
return "".join(s)
4. 从尾到头打印链表
用递归 or 栈
栈
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param listNode ListNode类
# @return int整型一维数组
#
class Solution:
def printListFromTailToHead(self, listNode: ListNode) -> list[int]:
printList = []
if not listNode:
return printList
stack = []
l = listNode
while l:
stack.append(l.val)
l = l.next
while stack:
val = stack.pop(-1)
printList.append(val)
return printList
递归
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param listNode ListNode类
# @return int整型一维数组
#
class Solution:
def printListFromTailToHead(self, listNode: ListNode) -> list[int]:
if not listNode:
return []
if not listNode.next:
return [listNode.val]
printList = self.printListFromTailToHead(listNode.next)
printList.append(listNode.val)
return printList
5.重建二叉树
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pre int整型一维数组
# @param vin int整型一维数组
# @return TreeNode类
#
class Solution:
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
if len(pre) == 0:
return None
root = TreeNode(pre[0])
if len(pre) == 1:
return root
rootIdx = 0
for i in range(len(vin)):
if vin[i] == pre[0]:
rootIdx = i
break
vinLeft,vinRight = vin[0:rootIdx],vin[rootIdx+1:len(vin)]
preLeft,preRight = pre[1:len(vinLeft)+1],pre[len(vinLeft)+1:len(pre)]
root.left = self.reConstructBinaryTree(preLeft,vinLeft)
root.right = self.reConstructBinaryTree(preRight,vinRight)
return root
6.二叉树的下一个结点
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
if not pNode:
return None
# 有右子树,右子树最左节点就是下个节点
if pNode.right:
p = pNode.right
while p.left:
p = p.left
return p
# 没有右子树,
else:
# 如果是父节点的左子树,则返回父节点,否则不断往上,直到满足这个条件
p = pNode
father = p.next
while father and father.left != p:
p = father
father = p.next
return father
7.用两个栈实现队列
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
self.stack1.append(node)
def pop(self):
if len(self.stack2) == 0:
while len(self.stack1):
self.stack2.append(self.stack1.pop(-1))
if len(self.stack2):
return self.stack2.pop(-1)
return None
8.斐波那契数列
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param n int整型
# @return int整型
#
class Solution:
def Fibonacci(self , n: int) -> int:
if n == 1 or n ==2:
return 1
f1,f2 = 1,1
cur = 2
while cur < n:
curSum = f1+f2
f1 = max(f1,f2)
f2 = curSum
cur += 1
return f2
8.旋转数组的最小数字
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param rotateArray int整型一维数组
# @return int整型
#
class Solution:
def minNumberInRotateArray(self, rotateArray):
if len(rotateArray) == 0:
return None
l,r = 0,len(rotateArray)-1
while l+1 < r:
mid = (l+r)//2
if rotateArray[l] < rotateArray[mid]:
l = mid
elif rotateArray[l] > rotateArray[mid]:
r = mid
# 2,2,2,1,2
# 2,1,2,2,2
else:
if rotateArray[r] < rotateArray[mid]:
l = mid
# 这里只能r走,否则出现顺序情况会无法判断
while rotateArray[l] == rotateArray[r] and l < r:
r -= 1
# 数组完全是顺序的情况
return min(min(rotateArray[l],rotateArray[r]),rotateArray[0])
反向写,相对来说不容易卡边界,但是我会有点想不清楚
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param rotateArray int整型一维数组
# @return int整型
#
class Solution:
def minNumberInRotateArray(self, rotateArray):
if len(rotateArray) == 0:
return None
l,r = 0,len(rotateArray)-1
while l+1 < r:
mid = (l+r)//2
if rotateArray[r] < rotateArray[mid]:
l = mid
elif rotateArray[r] > rotateArray[mid]:
r = mid
# 2,2,2,1,2
# 2,1,2,2,2
else:
if rotateArray[l] < rotateArray[mid]:
return rotateArray[l]
elif rotateArray[l] > rotateArray[mid]:
r = mid
while rotateArray[l] == rotateArray[r] and l < r:
l += 1
r -= 1
# 数组完全是顺序的情况
return min(rotateArray[l],rotateArray[r])
9.矩阵中的路径
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param matrix char字符型二维数组
# @param word string字符串
# @return bool布尔型
#
class Solution:
def __init__(self):
self.direction = [[-1,0],[1,0],[0,1],[0,-1]]
def hasPath(self , matrix: list[list[str]], word: str) -> bool:
if len(matrix) == 0 or len(matrix[0]) == 0:
return False
self.lenX = len(matrix)
self.lenY = len(matrix[0])
self.matrix = matrix
self.word = word
self.visited = [[0 for j in range(self.lenY)] for i in range(self.lenX)]
for i in range(self.lenX):
for j in range(self.lenY):
if self.dfs(i,j,0):
return True
return False
def dfs(self,x,y,n):
if n == len(self.word):
return True
# 注意不要漏掉x < 0 or y < 0的判断
if x < 0 or y < 0 or x >= self.lenX or y >= self.lenY or self.matrix[x][y] != self.word[n] or self.visited[x][y]:
return False
self.visited[x][y] = 1
for i,j in self.direction:
if self.dfs(x+i,y+j,n+1):
return True
self.visited[x][y] = 0
return False
10.机器人的运动范围
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param threshold int整型
# @param rows int整型
# @param cols int整型
# @return int整型
#
class Solution:
def __init__(self):
self.direction = [[-1,0],[1,0],[0,1],[0,-1]]
def movingCount(self , threshold: int, rows: int, cols: int) -> int:
if not rows or not cols or threshold < 0:
return 0
self.rows = rows
self.cols = cols
self.visited = [[0 for i in range(cols)] for j in range(rows)]
self.squireCnt = 0
self.dfs(0,0,threshold)
return self.squireCnt
def dfs(self,x,y,threshold):
if x >= self.rows or y >= self.cols or x < 0 or y < 0 or self.visited[x][y] == 1 or not self.checkNum(x,y,threshold):
return
self.visited[x][y] = 1
self.squireCnt += 1
for i,j in self.direction:
self.dfs(x+i,y+j,threshold)
def checkNum(self,x,y,threshold):
xysum = 0
while x:
xysum += x%10
x //= 10
while y:
xysum += y%10
y //= 10
if xysum > threshold:
return False
else:
return True
11.剪绳子
注意不要漏余数为0的判断
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param number int整型
# @return int整型
#
class Solution:
def cutRope(self , number: int) -> int:
# 8:2,3,3
# 10:1,3,3,3/2,3,3,2
cnt3 = number//3
remain = number%3
# 注意不要漏余数为0的判断
if remain == 0:
return pow(3,cnt3)
elif remain == 1:
return 4 * pow(3,cnt3-1)
else:
return 2 * pow(3,cnt3)
12.二进制中1的个数
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param n int整型
# @return int整型
#
class Solution:
def NumberOf1(self , n: int) -> int:
flag = 1
cnt = 0
for i in range(32):
if flag & n:
cnt += 1
flag <<= 1
return cnt
13.数值的整数次方
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param base double浮点型
# @param exponent int整型
# @return double浮点型
#
class Solution:
def Power(self , base: float, exponent: int) -> float:
if base == 0:
return 0
if exponent == 0 or base == 1:
return 1
isNeg = False
if exponent < 0:
isNeg = True
result = 1
exp = abs(exponent)
for i in range(exp):
result *= base
if isNeg:
return 1.0/result
return result
快速幂,具体解法参考之前文章
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param base double浮点型
# @param exponent int整型
# @return double浮点型
#
class Solution:
def Power(self , base: float, exponent: int) -> float:
if base == 0:
return 0
if exponent == 0 or base == 1:
return 1
isNeg = False
if exponent < 0:
isNeg = True
result = 1
exp = abs(exponent)
while exp:
if exp & 1:
result *= base
base *= base
exp = exp >> 1
if isNeg:
return 1.0/result
return result
14.删除链表的节点
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @param val int整型
# @return ListNode类
#
class Solution:
def deleteNode(self , head: ListNode, val: int) -> ListNode:
dummy = ListNode(-1)
dummy.next = head
p = dummy
while p.next:
if p.next.val == val:
p.next = p.next.next
p = p.next
return dummy.next
15.正则表达式匹配