0189. 轮转数组 - 力扣
1 切片取余
n = len(nums)
nums[:] = nums[-k % n:] + nums[:-k % n]
2 边删边插
for _ in range(k): nums.insert(0, nums.pop())
3 数组翻转
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k = k % n
self.reverse(nums, 0, n-1)
self.reverse(nums, 0, k-1)
self.reverse(nums, k, n-1)
def reverse(self, nums: List[int], left: int, right: int) -> None:
while left < right :
tmp = nums[left]
nums[left] = nums[right]
nums[right] = tmp
left += 1
right -= 1
数组前补0
digits = [0] + digits
range(n-1,-1,-1)
num[k-1::-1]
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
digits = [0] + digits
n=len(digits)
digits[n - 1] += 1
for i in range(n-1, 0, -1):
if digits[i] != 10:
break
else:
digits[i] = 0
digits[i - 1] += 1
if digits[0] == 0:
return digits[1:]
else:
return digits
除自身外相乘
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
size = len(nums)
res = [1 for _ in range(size)]
left = 1
for i in range(size):
res[i] *= left
left *= nums[i]
right = 1
for i in range(size-1, -1, -1):
res[i] *= right
right *= nums[i]
return res
对角线遍历
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
rows = len(mat)
cols = len(mat[0])
count = rows * cols
x, y = 0, 0
ans = []
for i in range(count):
ans.append(mat[x][y])
if (x + y) % 2 == 0:
# 最后一列
if y == cols - 1:
x += 1
# 第一行
elif x == 0:
y += 1
# 右上方向
else:
x -= 1
y += 1
else:
# 最后一行
if x == rows - 1:
y += 1
# 第一列
elif y == 0:
x += 1
# 左下方向
else:
x += 1
y -= 1
return ans
超牛,线性解法:
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
m, n, ans = len(mat), len(mat[0]), []
for k in range(m + n - 1):
if not k % 2:
ans += [mat[x][k-x] for x in range(min(m - 1, k), max(-1, k - n),-1)]
else:
ans += [mat[x][k-x] for x in range(max(0, k - n + 1), min(k + 1, m))]
return ans
首先要知道的是:
- 右斜对角线是横纵坐标和为定值(左斜的话是差为定值)。
- 一共有m+n−1个对角线,对应左上角贴边走到右下角
根据以上条件,可以推导每个对角线的横纵坐标范围,再确认一下从上到下还是从下到上即可。
# 已知 x + y = k 和 0 <= x < m 还有 0 <= y < n
# 0 <= x < m, 0 <= k - x < n
# 0 <= x < m, k - n < x <= k
python读取txt
datetime
import datetime
start = datetime.datetime(2000, 1, 1)
end = datetime.datetime(2020, 10, 1)
days = datetime.timedelta(days=1)
ans = 0
while end >= start:
if start.day == 1 or start.weekday() == 0:#周一为0
ans += 2
else:
ans += 1
start += days
print(ans)
import sys
import datetime
input=lambda :sys.stdin.readline().strip()
start=datetime.datetime(1970,1,1,0,0,0)
for i in range(int(input())):
a,b,c=input().split()
y,m,d=map(int,a.split('-'))
h,mi,s=map(int,b.split(':'))
now=datetime.datetime(y,m,d,h,mi,0)
diff=now-start
totmins=diff.total_seconds()//60%int(c)
print(str(now-datetime.timedelta(minutes=totmins)))
蛇形排列
i = 0
j = 0
num = 0
while True:
num += 1
if i == 19 and j == 19:
break
if (i+j)&1:
i += 1
if j > 0:
j -= 1
else:
j += 1
if i > 0:
i -= 1
print(num)
不同进制转换:
def convert(x,b):
digits="0123456789ABCDEF"
res=''
if x==0:
return '0'
while x:
res=str(digits[x%b])+res
x//=b
return res
#二进制
sum(int(i) for i in bin(x)[2:])
# 示例
decimal_num = 255
print(f"十进制数 {decimal_num} 转换为二进制: {convert_to_base(decimal_num, 2)}")
print(f"十进制数 {decimal_num} 转换为八进制: {convert_to_base(decimal_num, 8)}")
print(f"十进制数 {decimal_num} 转换为十六进制: {convert_to_base(decimal_num, 16)}")
试题 B: 数字串个数(满分)
小蓝想要构造出一个长度为 10000 的数字字符串,有以下要求:
\1) 小蓝不喜欢数字 0 ,所以数字字符串中不可以出现 0 ;
\2) 小蓝喜欢数字 3 和 7 ,所以数字字符串中必须要有 3 和 7 这两个数字。
请问满足题意的数字字符串有多少个?这个数字会很大,你只需要输出其
对 10 9 + 7 取余后的结果。
pow函数容斥原理
mod = 10**9 + 7
# 157509472
print((pow(9, 10000, mod) - 2 * pow(8, 10000, mod) + pow(7, 10000, mod)) % mod)
快速幂:
def fastExpMod(base, exponent, mod):
result = 1
while exponent > 0:
if exponent & 1: # 判断当前位是否为1
result = (result * base) % mod
base = (base * base) % mod # 底数平方并取模
exponent >>= 1 # 指数右移一位
return result
dp
def main():
n = 10000
p = int(1e9 +7)
dp = [[[0] * 2 for i in range(2)] for j in range(n+1)]
# 前缀指的是不包括当前字符串的前子串
# 状态为[当前str长度][前缀是否有3][前缀是否有7]
# 边界
dp[1][0][0] = 7 # 没有3和7,只能是除37的其它七种方案
dp[1][0][1] = 1 # 有3,一种方案
dp[1][1][0] = 1 # 有7,一种方案
dp[1][1][1] = 0 # 有3和7,不可能(长度为1不可能同时出现37)
# 枚举阶段,决策为当前i位置填什么字符
for i in range(2, n+1):
# 状态转移
dp[i][0][0] = (dp[i-1][0][0] * 7) % p # 前缀无37(当前可填7种1、2、4、5、6、8、9)
dp[i][0][1] = (dp[i-1][0][1] * 8 + dp[i-1][0][0]) % p # 从有7(可填8种)、和均没有(可填1种)
dp[i][1][0] = (dp[i-1][1][0] * 8 + dp[i-1][0][0]) % p # 从有3(可填8种)、和均没有(可填1种)
dp[i][1][1] = (dp[i-1][1][1] * 9 + dp[i-1][0][1] + dp[i-1][1][0]) % p # 从有37(可填9种)、只有3(1种)、只有7(1种)三种情况
# 答案
print(dp[n][1][1]) # 157509472
if __name__ == '__main__':
main()
dxdy找边界
n,m=map(int,input().split())
lst = []
for _ in range(n):
lst.append(list(map(int, input().split())))
ans=0
dic={(1,1),(1,-1)}
for i in range(n):
for j in range(m):
s=0
for dx,dy in dic:
x,y=i,j
while 0<=x+dx<n and 0<=y+dy<m:
x+=dx
y+=dy
if lst[x][y]==lst[i][j]:
s=s+1
ans+=s
print(ans*2)
counter
from collections import Counter
# 使用字符串初始化Counter
counter = Counter("mississippi")
print(counter) # 输出: Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})
# 使用列表初始化Counter
counter = Counter(list("mississippi"))
print(counter) # 输出: Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})
更新Counter
Counter的update()方法会将现有计数相加,而不是替换它们。
counter = Counter({'a': 3, 'b': 2})
counter.update({'a': 1, 'c': 2})
print(counter) # 输出: Counter({'a': 4, 'b': 2, 'c': 2})
访问Counter的内容
counter = Counter("mississippi")
print(counter['s']) # 输出: 4
for letter in counter:
print(letter, counter[letter])
查找最常见的对象
如果你需要根据对象的出现频率列出一组对象,你可以使用most_common()方法。这个方法返回一个按对象当前计数排序的(对象, 计数)列表。如果计数相等,则按它们首次出现的顺序排列。
counter = Counter('mississippi')
print(counter.most_common(3)) # 输出: [('i', 4), ('s', 4), ('p', 2)]
使用Counter作为多重集
Counter实例也可以作为多重集(multiset)使用,这是数学中的一个概念,允许集合中的元素有多个实例。例如,你可以有一个多重集{1, 1, 2, 3, 3, 3, 4, 4},但集合版本将限制为{1, 2, 3, 4}。
counter = Counter([1, 1, 2, 3, 3, 3, 4, 4])
print(counter) # 输出: Counter({3: 3, 1: 2, 4: 2, 2: 1})
快读
import sys
input = lambda: sys.stdin.readline().strip()