LeetCode之骚操作

本文介绍了解决特定类型问题的两种高效算法:滑动窗口和前缀和。滑动窗口算法用于寻找乘积小于k的连续子数组个数;前缀和算法结合哈希表快速解决和为k的连续子数组问题。文章还涵盖了ASCII码、最小公倍数计算、以及几种常见的岛屿问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

滑动窗口

乘积小于 k 的连续的子数组

给定一个正整数数组 nums和整数 k ,请找出该数组内乘积小于 k 的连续的子数组的个数

思想:关键的点在于记录个数的时候,某个窗口内的子数组个数大小 right-left+1,是因为我们需要从右边开始数,如果从左边开始就有重复。
比如某次遍历符合题意的子数组为 ABCX,那么在该条件下符合条件的有X,CX,BCX,ABCX共四个(可以进行多个例子,发现个数符合right-left+1)

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        left, res = 0, 0
        total = 1
        for right,num in enumerate(nums):
            total *= num
            while left <= right and total >= k: 
                total //= nums[left]	### key point
                left += 1 
            if left <= right:
                res += right-left+1  ### key point
        return res

前缀和

和为 k 的连续子数组

给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
思想:前缀和+哈希。求数组前缀和,并且将当前的前缀和存到哈希表中,每次求出一个前缀和只需要判断preSum[i] - k在没在前面出现过即可

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        presum_map = defaultdict(int)
        presum_map[0] = 1
        presum, ans = 0, 0

        for i in range(len(nums)):
            presum += nums[i]
            target = presum - k
            if target in presum_map:
                ans += presum_map[target]
            presum_map[presum] += 1
        
        return ans

ascii码

码与数字的转换

ord('a')
chr(65)
0--48
A--65
a--97

最小公倍数

在最大的数的倍数里面去找能整除另一个数的数就是最小公倍数,按照大的数来找来降低循环的次数

while True:
    try:
        a, b = list(map(int, input().split())) 
       
        if a < b: 
            a,b = b,a
        for i in range(a, a*b+1, a):
            if i % b == 0:
                print(i)
                break 
    except:
        break

岛屿问题

岛屿数量

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        row, col, ret = len(grid), len(grid[0]), 0
        def dfs(x,y):
            grid[x][y] = '0' 	# 遍历过的标记为 0
            for c in [[0,1], [0,-1], [-1,0], [1,0]]:
                nx, ny = x+c[0], y+c[1]
                if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == '1':
                    dfs(nx, ny) 
        for i in range(row):
            for j in range(col):
                if grid[i][j] == '1':
                    dfs(i,j)
                    ret += 1
        return ret

岛屿的周长

遇到边界或者是水的话就+1

class Solution:
    def islandPerimeter(self, grid: List[List[int]]) -> int:
        row, col = len(grid), len(grid[0])

        def dfs(grid, i, j):
            if not 0 <= i < row or not 0 <= j < col:  # 边界
                return 1
            if grid[i][j] == 0:		# 水
                return 1
            if grid[i][j] != 1:		# 已经遍历过
                return 0
            grid[i][j] = 2		# 标记已经遍历过的

            return dfs(grid, i-1, j) + dfs(grid, i, j-1) + dfs(grid, i+1, j) + dfs(grid, i, j+1)

        for i in range(row):
            for j in range(col):
                if grid[i][j] == '1':
                    return dfs(grid, i, j)

在这里插入图片描述

岛屿的最大面积

想法就是每找到一个岛,数一数里边1的个数

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        row, col, max_ = len(grid), len(grid[0]), 0
        def dfs(grid, i, j):
            if not 0 <= i < row or not 0 <= j < col or not grid[i][j]:
                return
            grid[i][j] = 0
            self.res += 1
            dfs(grid, i, j+1)
            dfs(grid, i, j-1)
            dfs(grid, i-1, j)
            dfs(grid, i+1, j)
            return self.res
        for i in range(row):
            for j in range(col):
                if grid[i][j] == 1:
                    self.res = 0                    
                    max_ = max(max_, dfs(grid, i ,j))        
        return max_

统计子岛屿

有两个岛屿,如果 grid2 的一个岛屿,被 grid1 的一个岛屿 完全 包含,也就是说 grid2 中该岛屿的每一个格子都被 grid1 中同一个岛屿完全包含,那么我们称 grid2 中的这个岛屿为 子岛屿 。

class Solution:
    def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int:
        row, col = len(grid1), len(grid1[0])

        def dfs(grid, i, j):
            grid[i][j] = 0	# 将搜索过的岛屿置0,防止重复搜索
            for c in [[-1,0], [1,0], [0,-1], [0,1]]:
                n_i, n_j = i+c[0], j+c[1]
                if 0<= n_i < row and 0 <= n_j < col and grid[n_i][n_j] == 1:   # 搜索点符合要求且为陆地
                    dfs(grid, n_i, n_j)
# 首先将2中岛屿不被1中包含的剔除掉
        for i in range(row):
            for j in range(col):
                if grid2[i][j] == 1 and grid1[i][j] == 0:
                    dfs(grid2, i, j)

        res = 0
        for i in range(row):
            for j in range(col):
                if grid2[i][j] == 1: 
                    dfs(grid2, i, j)
                    res += 1

        return res        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值