leetcode刷题记录401-410 python版

前言

继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬

401. 二进制手表

# 数下1
class Solution:
    def readBinaryWatch(self, num: int) -> List[str]:
        res = []
        for h in range(12):
            for m in range(60):
                if bin(h).count("1") + bin(m).count("1") == num:
                    res.append("{}:{:02d}".format(h, m))
        return res

402. 移掉K位数字

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        l = len(num)
        if l == k: return "0"
        # 维护一个单调增的队列
        stack = []
        cnt = k
        for n in num:
            while stack and stack[-1] > n and k:
                stack.pop()
                k -= 1
            stack.append(n)
        return str(int("".join(stack[:l - cnt])))

403. 青蛙过河

# 动态规划
class Solution:
    def canCross(self, stones: List[int]) -> bool:
        n = len(stones)
        dp = [[False] * n for _ in range(n)]
        dp[0][1] = True
        for i in range(1, n):
            for j in range(i):
                distance = stones[i] - stones[j]
                if distance < 0 or distance >= n or not dp[j][distance]:
                    continue
                dp[i][distance] = True
                if distance - 1 >= 0: dp[i][distance - 1] = True
                if distance + 1 < n: dp[i][distance + 1] = True
        return any(dp[-1])
# 记忆+回溯
class Solution:
    def canCross(self, stones: List[int]) -> bool:
        from functools import lru_cache
        end = stones[-1]
        s = set(stones)
        @lru_cache(None)
        def helper(start, jump):
            # 结束标志
            if start == end:
                return True
            # 对应3种跳法
            for j in [jump - 1, jump, jump + 1]:
                if j <= 0: continue
                if start + j in s and helper(start + j, j):
                    return True
            return False
        return helper(0, 0)

404. 左叶子之和

class Solution:
    def sumOfLeftLeaves(self, root: TreeNode) -> int:
        self.res = 0
        def helper(root):
            if not root: return 0
            if root.left and not root.left.left and not root.left.right:
                self.res += root.left.val
            helper(root.left)
            helper(root.right)
        tmp = root
        helper(tmp)
        return self.res

405. 数字转换为十六进制数

# 位运算
class Solution:
    def toHex(self, num: int) -> str:
        num &= 0xFFFFFFFF
        s = "0123456789abcdef"
        res = ""
        mask = 0b1111
        while num > 0:
            res += s[num & mask]
            num >>= 4
        return res[::-1] if res else "0"
# 分类
class Solution:
    def toHex(self, num: int) -> str:
        if num == 0: return '0'
        res = ''
        if num < 0:
            num = (abs(num) ^ ((2 ** 32) - 1)) + 1
        while (num >> 4) > 0 or num > 0:
            a = str(num % 16)
            if a == '10':
                a = 'a'
            elif a == '11':
                a = 'b'
            elif a == '12':
                a = 'c'
            elif a == '13':
                a = 'd'
            elif a == '14':
                a = 'e'
            elif a == '15':
                a = 'f'
            res += a
            num = num >> 4
        return ''.join(reversed(res))

406. 根据身高重建队列

# 先排序再插队
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=lambda x: (-x[0], x[1]))
        res = []
        for p in people:
            res.insert(p[1], p)
        return res

407. 接雨水 II

# 从最外围开始
class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        import heapq
        row, col = len(heightMap), len(heightMap[0])
        hp = []
        visited = [[False for _ in range(col)] for _ in range(row)]
        # 最外围围栏入堆
        for i in range(row):
            for j in range(col):
                if i == 0 or j == 0 or i == row - 1 or j == col - 1:
                    # 最小堆,保证最矮的围栏出堆
                    heapq.heappush(hp, (heightMap[i][j], i, j))
                    visited[i][j] = True
        res = 0
        while hp:
            h, r, c = heapq.heappop(hp)
            for nr, nc in ((r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)):
                if 0 <= nr < row and 0 <= nc < col and not visited[nr][nc]:
                    # 围栏比内部高,可以灌水
                    if h > heightMap[nr][nc]:
                        res += h - heightMap[nr][nc]
                    # 忽略当前围栏,在(nr, nc)处新建围栏
                    visited[nr][nc] = True
                    # 新的围栏入堆
                    heapq.heappush(hp, (max(h, heightMap[nr][nc]), nr, nc))
        return res

409. 最长回文串

class Solution:
    def longestPalindrome(self, s: str) -> int:
        import string
        flag = 0
        res = 0
        for a in string.ascii_letters:
            num = s.count(a)
            if num % 2 == 0:
                res += num
            else:
                flag = 1
                res += num - 1
        return res + flag

410. 分割数组的最大值

# 二分
class Solution:
    def splitArray(self, nums: List[int], m: int) -> int:
        left = max(nums)
        right = sum(nums)
        while left < right:
            mid = (left + right) // 2
            sums, cnt = 0, 1
            for i in nums:
                if sums + i > mid:
                    cnt += 1
                    sums = i
                else:
                    sums += i
            if cnt <= m:
                right = mid
            else:
                left = mid + 1
        return left

猜你喜欢

转载自blog.csdn.net/weixin_44604541/article/details/106833879