LeetcodePython笔记

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

首先要知道的是:

  1. 右斜对角线是横纵坐标和为定值(左斜的话是差为定值)。
  2. 一共有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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值