leetcode专栏2

目录

跳跃游戏I

跳跃游戏II

接雨水

搜索插入位置

路径总和

路径总和II

合并两个有序链表

合并排序链表中的重复元素II

LRU缓存

去除重复元素

组合

电话号码的字母组合

括号生成

颠倒二进制位

只出现一次的数字

单词搜索

移动0(HOT100)

找到字符串中所有字母异位词(HOT100)

螺旋矩阵

旋转图像


跳跃游戏I

求最长跳跃距离问题

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n, rightmost = len(nums), 0
        for i in range(n):
            if i <= rightmost:
                rightmost = max(rightmost, i + nums[i])
            if rightmost >= n-1:
                return True
        return False

跳跃游戏II

求最短跳跃次数问题,相比较I增加一层if判断

class Solution:
    def jump(self, nums: List[int]) -> int:
        n = len(nums)
        maxpos = 0
        std = 0
        end = 0
        for i in range(n-1):
            if i <= maxpos:
                maxpos = max(maxpos, i + nums[i])
                if i == end:
                    end = maxpos
                    std += 1
        return std

接雨水

class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        #时间复杂度O(n), 空间复杂度O(n)
        # right = [0] * n
        # left = [0] * n
        # max1, max2 = 0, 0
        # ansx = 0
        # for i in range(n):
        #     max1 = max(height[i], max1)
        #     right[i] = max1
        # for i in range(n-1, -1, -1):
        #     max2 = max(height[i], max2)
        #     left[i] = max2
        # for i in range(n):
        #     ansx += max((min(left[i], right[i]) -height[i]), 0)
        # return ansx
        时间复杂度O(n),空间复杂度O(1)
        i, j = 0, n-1
        ans = 0
        max_left, max_right = 0, 0
        while(i<=j):
            max_left = max(max_left, height[i])
            max_right = max(max_right, height[j])
            if max_left < max_right:
                ans += max_left-height[i]
                i += 1
            else:
                ans += max_right-height[j]
                j -= 1
        return ans

搜索插入位置

自己写的:

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        n = len(nums)
        if target > nums[n-1]:
            return n
        for i in range(n):
            if target > nums[i]:
                continue
            else:
                return i

别人写的:

def lower_bound(nums: List[int], target: int) -> int:

    left, right = 0, len(nums) - 1  # 闭区间 [left, right]

    while left <= right:  # 区间不为空

        mid = (left + right) // 2

        if nums[mid] < target:

            left = mid + 1  # 范围缩小到 [mid+1, right]

        else:

            right = mid - 1  # 范围缩小到 [left, mid-1]

    return left


class Solution:

    def searchInsert(self, nums: List[int], target: int) -> int:

        return lower_bound(nums, target) 


#库函数写法
class Solution:

    def searchInsert(self, nums: List[int], target: int) -> int:

        return bisect_left(nums, target)

路径总和

求是否有总和为k的路径

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        if not root.left and not root.right:
            return targetSum == root.val
        return self.hasPathSum(root.left, targetSum-root.val) or self.hasPathSum(root.right, targetSum-root.val)

路径总和II

求出所有总和为k的路径

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        ans = []
        path = []

        def dfs(root, targetSum):
            if not root:
                return
            path.append(root.val)
            targetSum -= root.val
            if not root.left and not root.right and targetSum == 0:
                ans.append(path[:])
            dfs(root.left, targetSum)
            dfs(root.right, targetSum)
            path.pop()

        dfs(root, targetSum)
        return ans

合并两个有序链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        prehead = ListNode(-1)
        prev = prehead
        while l1 and l2:
            if l1.val <= l2.val:
                prev.next = l1
                l1 = l1.next
            else:
                prev.next = l2
                l2 = l2.next            
            prev = prev.next

        # 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 if l1 is not None else l2
        return prehead.next

合并排序链表中的重复元素II

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy = cur = ListNode(next = head)
        while cur.next and cur.next.next:
            val = cur.next.val
            if cur.next.next.val == val:
                while cur.next and cur.next.val == val:
                    cur.next = cur.next.next
            else:
                cur = cur.next
        return dummy.next

LRU缓存

库函数版本

class LRUCache(collections.OrderedDict):

    def __init__(self, capacity: int):
        super().__init__()
        self.capacity = capacity

    def get(self, key: int) -> int:
        if key not in self:
            return -1
        self.move_to_end(key)
        return self[key]


    def put(self, key: int, value: int) -> None:
        if key in self:
            self.move_to_end(key)
        self[key] = value
        if len(self) > self.capacity:
            self.popitem(last = False)

正常版本

class DLinkedNode:
    def __init__(self, key=0, value=0):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None


class LRUCache:

    def __init__(self, capacity: int):
        self.cache = dict()
        # 使用伪头部和伪尾部节点    
        self.head = DLinkedNode()
        self.tail = DLinkedNode()
        self.head.next = self.tail
        self.tail.prev = self.head
        self.capacity = capacity
        self.size = 0

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        # 如果 key 存在,先通过哈希表定位,再移到头部
        node = self.cache[key]
        self.moveToHead(node)
        return node.value

    def put(self, key: int, value: int) -> None:
        if key not in self.cache:
            # 如果 key 不存在,创建一个新的节点
            node = DLinkedNode(key, value)
            # 添加进哈希表
            self.cache[key] = node
            # 添加至双向链表的头部
            self.addToHead(node)
            self.size += 1
            if self.size > self.capacity:
                # 如果超出容量,删除双向链表的尾部节点
                removed = self.removeTail()
                # 删除哈希表中对应的项
                self.cache.pop(removed.key)
                self.size -= 1
        else:
            # 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
            node = self.cache[key]
            node.value = value
            self.moveToHead(node)
    
    def addToHead(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next.prev = node
        self.head.next = node
    
    def removeNode(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev

    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)

    def removeTail(self):
        node = self.tail.prev
        self.removeNode(node)
        return node

去除重复元素

单个字符串去除

def merge_and_deduplicate(s):
    result_list = []
    for char in s:
        # 如果字符不在结果列表中,则添加
        if char not in result_list:
            result_list.append(char)
            # 将结果列表转换为字符串并返回
    return ''.join(result_list)

# 示例
strings = "AprogramAmiFng"
result = merge_and_deduplicate(strings)
print(result)  # 输出:'helordpwtgmin'

多个字符串合并去除

def merge_and_deduplicate(strings):
    result_list = []
    for s in strings:
        for char in s:
            if char not in result_list:
                result_list.append(char)
    return ''.join(result_list)
strings = ["hello", "world", "python", "programming"]
result = merge_and_deduplicate(strings)
print(result)

组合

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        path, ans = [], []
        def dfs(i, k):
            if k == 0:
                ans.append(path[:])
                return
            for j in range(i, n+1):
                path.append(j)
                dfs(j + 1, k-1)
                path.pop()
        dfs(1, k)
        return ans

电话号码的字母组合

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        hashx = {
            "2":'abc',
            '3':'def',
            '4':'ghi',
            '5':'jkl',
            '6':'mno',
            '7':'pqrs',
            '8':'tuv',
            '9':'wxyz'
        }
        if len(digits) == 0:
            return []
        ans, path = [], []
        length = len(digits)
        def dfs(i):
            if i == length:
                ans.append(''.join(path))
                return
            c = digits[i]
            for value in hashx[c]:
                path.append(value)
                dfs(i+1)
                path.pop()
        dfs(0)
        return ans

括号生成

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        # def generate(A):
        #     if len(A) == 2*n:
        #         if valid(A):
        #             ans.append("".join(A))
        #             return
        #     else:
        #         A.append('(')
        #         generate(A)
        #         A.pop()
        #         A.append(')')
        #         generate(A)
        #         A.pop()
        # def valid(A):
        #     bal = 0
        #     for c in A:
        #         if c == '(': bal += 1
        #         else: bal -= 1
        #         if bal < 0: return False
        #     return bal == 0
        # ans = []
        # generate([])
        # return ans
        ans = []
        def dfs(S, left, right):
            if len(S) == 2*n:
                ans.append("".join(S))
                return
            if left < n:
                S.append('(')
                dfs(S, left+1, right)
                S.pop()
            if right < left:
                S.append(')')
                dfs(S, left, right+1)
                S.pop()
        dfs([], 0, 0)
        return ans

颠倒二进制位

class Solution:
    def reverseBits(self, n: int) -> int:
        res = 0
        for i in range(32):
            res = (res<<1) | (n&1)
            n >>= 1
        return res
        

只出现一次的数字

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        # nums.sort()
        # # print(nums)
        # flag = 0
        # n = len(nums)
        # if len(nums) == 1:
        #     return nums[0]
        # if nums[0] != nums[1]:
        #     return nums[0]
        # if nums[n-2]!= nums[n-1]:
        #     return nums[n-1]
        # for i in range(1, len(nums)-1):
        #     if nums[i+1] == nums[i] or nums[i] == nums[i-1]:
        #         continue
        #     else:
        #         flag = nums[i]
        # return flag
        return reduce(lambda x,y:x^y, nums)

单词搜索

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        directions = [
            (-1, 0),
            (1, 0),
            (0,1),
            (0,-1)
        ]
        def dfs(i, j, k):
            if board[i][j] != word[k]:
                return False
            if k == len(word)-1:
                return True

            visited.add((i,j))
            result = False

            for di, dj in directions:
                newi = i + di
                newj = j + dj
                if 0<=newi<len(board) and 0<= newj < len(board[1]):
                    if (newi, newj) not in visited:
                        if dfs(newi, newj, k + 1):
                            result = True
                            break
            visited.remove((i, j))
            return result
            
        h, w = len(board), len(board[0])
        visited = set()
        for i in range(h):
            for j in range(w):
                if dfs(i, j, 0):
                    return True

        return False

移动0(HOT100)

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # n = len(nums)
        # if n <= 1:
        #     return nums
        # # for i in range(n):
        # for j in range(n-1):
        #     if nums[j] == 0:
        #         k = j + 1
        #         while k < n-1 and nums[k] == 0:
        #             k += 1
        #         q = nums[k]
        #         nums[k] = 0
        #         nums[j] = q
        #     else:
        #         continue
        # return nums
        if not nums:
            return 0
        j = 0
        for i in range(len(nums)):
            if nums[i]:
                nums[j] = nums[i]
                j += 1
        for i in range(j, len(nums)):
            nums[i] = 0
        

找到字符串中所有字母异位词(HOT100)

自己的超时版本:

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        ans = []
        left = 0
        right = len(s)-1
        if len(s) == len(p):
            if sorted(s) == sorted(p):
                return [0]
            else:
                return []
        while left <= right-len(p) + 1:
            while s[left] not in p and left < right-len(p) + 1:
                left += 1
            if sorted(s[left:left+len(p)]) == sorted(p):
                ans.append(left)
            left += 1
        return ans 

使用Counter()计数器

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        n, m = len(s), len(p)
        cntp = Counter(p)
        cnts = Counter()
        ans = []
        for i, x in enumerate(s):
            cnts[x] += 1
            if i+1 >= m:
                if cntp == cnts:
                    ans.append(i+1-m)
                cnts[s[i+1-m]] -= 1
        return ans

螺旋矩阵

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        len_x = len(matrix)
        len_y = len(matrix[0])
        ans = []
        left, top = 0, 0
        right, bottom = len_y-1, len_x-1
        while(True):
            for i in range(left, right+1):
                ans.append(matrix[top][i])
            top += 1
            if top>bottom:break
            for i in range(top, bottom+1):
                ans.append(matrix[i][right])
            right -= 1
            if right<left:break
            for i in range(right,left-1,-1):
                ans.append(matrix[bottom][i])
            bottom -= 1
            if bottom<top:break
            for i in range(bottom, top-1, -1):
                ans.append(matrix[i][left])
            left += 1
            if left>right:break
        return ans

旋转图像

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        for i in range(n//2):
            for j in range((n+1)//2):
                matrix[i][j], matrix[n-j-1][i], matrix[n-i-1][n-j-1], matrix[j][n-1-i] = matrix[n-j-1][i], matrix[n-i-1][n-j-1], matrix[j][n-1-i], matrix[i][j]
        return matrix

一个小组的最大实力

自己写的shi山

class Solution:
    def maxStrength(self, nums: List[int]) -> int:
        nums.sort()
        abs_num = 0
        ans = 1
        for i in nums:
            if i < 0:
                abs_num += 1
            if i != 0:
                ans *= i
        if len(nums) <= 1:
            return int(nums[0])
        elif abs_num == 0 and nums[-1] == 0:
            return 0
        elif abs_num == 1 and nums[-1]==0:
            return 0
        elif abs_num%2 == 1:
            return int(ans / nums[abs_num-1])
        else:
            return int(ans)
        

别人的:

class Solution:
    def maxStrength(self, nums: List[int]) -> int:
        mn = mx = nums[0]
        for x in nums[1:]:
            mn, mx = min(mn, x, mx*x, mn*x), max(mx, x, mx*x, mn*x)
        return mx

字符串中的额外字符

这题还没太会,动态规划

class Solution:
    def minExtraChar(self, s: str, dictionary: List[str]) -> int:
        d = set(dictionary)
        @cache
        def dfs(i:int):
            if i < 0:
                return 0
            res = dfs(i-1) + 1
            for j in range(i+1):
                if s[j:i+1] in d:
                    res = min(res, dfs(j-1))
            return res
        return dfs(len(s)-1)

倍数求和

自己写的

class Solution:
    def sumOfMultiples(self, n: int) -> int:
        ans_set = set()
        for i in range(1, n+1):
            if i % 3 == 0:
                ans_set.add(i)
            if i % 5 == 0:
                ans_set.add(i)
            if i % 7 == 0:
                ans_set.add(i)
        ans = 0 
        for x in ans_set:
            ans += x
        return ans
#优化
    def sumOfMultiples(self, n: int) -> int:
        res = 0
        for i in range(1, n+1):
            if i % 3 == 0 or i % 5 == 0 or i % 7 == 0:
                res += i
        return res

别人的

class Solution:
    def sumOfMultiples(self, n: int) -> int:
        def f(m: int) -> int:
            return (m + n // m * m) * (n // m) // 2
        return f(3) + f(5) + f(7) - f(3 * 5) - f(3 * 7) - f(5 * 7) + f(3 * 5 * 7)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值