leetcode刷题记录371-380 python版

前言

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

371. 两整数之和

# 位运算
class Solution(object):
    def getSum(self, a, b):
        """
        :type a: int
        :type b: int
        :rtype: int
        """
        # 2^32
        MASK = 0x100000000
        # 整型最大值
        MAX_INT = 0x7FFFFFFF
        MIN_INT = MAX_INT + 1
        while b != 0:
            # 计算进位
            carry = (a & b) << 1
            # 取余范围限制在 [0, 2^32-1] 范围内
            a = (a ^ b) % MASK
            b = carry % MASK
        return a if a <= MAX_INT else ~((a % MIN_INT) ^ MAX_INT)
# 偷鸡
class Solution(object):
    def getSum(self, a, b):
        return sum([a, b])

372. 超级次方

# (xy)%k=(x%k)(y%k)%k
class Solution:
    def superPow(self, a: int, b: List[int]) -> int:
        if not b: return 1
        tmp = b.pop()
        return (((self.superPow(a, b)) ** 10) % 1337 * (a ** tmp) % 1337 ) % 1337

373. 查找和最小的K对数字

# 暴力
def kSmallestPairs(self, nums1, nums2, k):
    import itertools
    return map(list, sorted(itertools.product(nums1, nums2), key=sum)[:k])
# 堆
class Solution:
    def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:
        import heapq
        res = []
        queue = []
        if not nums1 or not nums2:
            return []
        heapq.heappush(queue, (nums1[0] + nums2[0], (0, 0)))
        # 防止重复加入
        visited = {(0, 0)}
        while queue and len(res) < k:
            _, (i, j) = heapq.heappop(queue)
            res.append((nums1[i], nums2[j]))
            # 每次nums1 或者 nums2 移动 
            if i + 1 < len(nums1) and (i + 1, j) not in visited:
                heapq.heappush(queue, (nums1[i + 1] + nums2[j], (i + 1, j)))
                visited.add((i + 1, j))
            if j + 1 < len(nums2) and (i, j + 1) not in visited:
                heapq.heappush(queue, (nums1[i] + nums2[j + 1], (i, j + 1)))
                visited.add((i, j + 1))
        return res

374. 猜数字大小

# 二分
class Solution:
    def guessNumber(self, n: int) -> int:
        left = 1
        right = n
        while left < right:
            mid = (left + right) // 2
            if guess(mid) == 1:
                left = mid + 1
            else:
                right = mid
        return left

375. 猜数字大小 II

class Solution:
    def getMoneyAmount(self, n: int) -> int:
        @functools.lru_cache(maxsize=None)
        def sol(l, r) :
            if r-l == 2 : return l
            if r-l <= 1 : return 0
            return min((i+max(sol(l,i), sol(i+1,r)) for i in range(l, r)))
        return sol(1,n+1)

376. 摆动序列

# 动态规划
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        # dp 记录 i位置前一个位置是上升, 还是下降dp[i][0]表示下降 dp[i][1] 表示上升
        if not nums: return 0
        dp = [[1] * 2 for _ in range(len(nums))]
        for i in range(1, len(nums)):
            # 上升到下降
            if nums[i - 1] > nums[i]:
                dp[i][0] = dp[i - 1][1] + 1
                dp[i][1] = dp[i - 1][1]
            elif nums[i - 1] < nums[i]:
                dp[i][1] = dp[i - 1][0] + 1
                dp[i][0] = dp[i - 1][0]
            else:
                dp[i][0] = dp[i - 1][0]
                dp[i][1] = dp[i - 1][1]
        return max(dp[-1])

377. 组合总和 Ⅳ

# 动态规划
class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        from collections import defaultdict
        dp = defaultdict(int)
        dp[0] = 1
        for i in range(1, target + 1):
            for num in nums:
                dp[i] += dp[i - num]
        return dp[target]

378. 有序矩阵中第K小的元素

class Solution:
    def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
        n = len(matrix)
        left = matrix[0][0]
        right = matrix[-1][-1]
        def search_less_equal(mid):
            i = 0
            j = n - 1
            res = 0
            while i < n and j >= 0:
                if matrix[i][j] <= mid:
                    res += (j + 1)
                    i += 1
                else:
                    j -= 1
            return res
        while left < right:
            mid = (left + right) // 2
            num = search_less_equal(mid)
            if num < k:
                left = mid + 1
            else:
                right = mid
        return left

380. 常数时间插入、删除和获取随机元素

import random
class RandomizedSet:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.a = set()
    def insert(self, val: int) -> bool:
        """
        Inserts a value to the set. Returns true if the set did not already contain the specified element.
        """
        if val not in self.a:
            self.a.add(val)
            return True
        return False
    def remove(self, val: int) -> bool:
        """
        Removes a value from the set. Returns true if the set contained the specified element.
        """
        if val in self.a:
            self.a.remove(val)
            return True
        return False
    def getRandom(self) -> int:
        """
        Get a random element from the set.
        """
        return random.choice(list(self.a))

猜你喜欢

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