Leetcode Hot 200 上

本文列举了LeetCode中的一些热门算法题目,包括链表操作、数组处理、字符串问题、二叉树遍历等,旨在提升编程能力和算法思维。涉及题目如无重复字符的最长子串、LRU缓存、翻转链表等。
摘要由CSDN通过智能技术生成

3. 无重复字符的最长子串

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        res = 0
        visited = list()
        # 先左移后右移窗口
        for i in range(len(s)):
            # 左移窗口
            while s[i] in visited: visited.pop(0)
            # 右移窗口
            visited.append(s[i])
            res = max(res, len(visited))
        return res

206. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre, cur = None, head
        while cur:
            # 存储当前链表的下一个节点为临时变量
            tmp = cur.next
            # 当前链表的下一个指向前一个链表
            cur.next = pre
            # pre, cur整体往后移动一个位置
            pre, cur = cur, tmp
        return pre

146. LRU 缓存

from collections import OrderedDict
class LRUCache:
 
    def __init__(self, capacity: int):
        # OrderedDict的key会按照插入的顺序排列,不是key本身排序
        self.capacity = capacity
        self.dict = OrderedDict()
 
    def get(self, key: int) -> int:
        # 说明在字典中,重新移动字典的尾部
        if key in self.dict:
            self.dict.move_to_end(key)
        return self.dict.get(key, -1)
 
    def put(self, key: int, value: int) -> None:
        # 如果存在,删掉,重新赋值
        if key in self.dict:
            del self.dict[key]
        # 在字典尾部添加
        self.dict[key] = value
        if len(self.dict) > self.capacity:
            # 弹出字典的头部(因为存储空间不够了)
            # OrderedDict.popitem()有一个可选参数last(默认为True),当last为True时它从OrderedDict中删除最后一个键值对并返回该键值对,当last为False时它从OrderedDict中删除第一个键值对并返回该键值对
            self.dict.popitem(last=False)
 
 
 
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

215. 数组中的第K个最大元素

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def quick_sort(a, l, r, k):
            if l >= r: return a[l]
            i = l - 1; j = r + 1
            x = a[l + r >> 1]
            while i < j:
                i += 1
                while a[i] < x: i += 1
                j -= 1
                while a[j] > x: j -= 1
                if i < j: a[i], a[j] = a[j], a[i]
            s1 = j - l + 1
            if k <= s1: return quick_sort(a, l, j, k)
            else: return quick_sort(a, j + 1, r, k - s1)
        return quick_sort(nums, 0, len(nums) - 1, len(nums) - k + 1)
# 第k个数是正序,本题是逆序

25. K 个一组翻转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
 
        # 判断是否有k个节点
        def cal_len(head):
            p = head
            cnt = 0
            while p:
                cnt += 1
                p = p.next
                if cnt >= k: return True
            return False
 
        # 翻转k个节点
        def reverseK(head, k):
            pre, cur = None, head
            while k:
                tmp = cur.next
                cur.next = pre
                pre, cur = cur, tmp
                k -= 1
            return pre, cur
 
        # 递归
        def dfs(head, k):
            if not cal_len(head): return head
            pre, cur = reverseK(head, k)
            head.next = dfs(cur, k)
            return pre
        
        return dfs(head, k)

15. 三数之和

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        n = len(nums)
        nums.sort()
        for i in range(n):
            l = i + 1; r = n - 1
            # 减枝,可省略
            if nums[i] > 0: break
            # nums[i] 去重,一定使用 i - 1
            if i > 0 and nums[i] == nums[i-1]: continue
            while l < r:
                sums = nums[i] + nums[l] + nums[r]
                if sums < 0: l += 1
                elif sums > 0: r -= 1
                else:
                    res.append([nums[i], nums[l], nums[r]])
                    # nums[l] nums[r] 去重
                    while l < r and nums[l] == nums[l+1]: l += 1
                    while l < r and nums[r] == nums[r-1]: r -= 1
                    # 最后再多走一步
                    l += 1; r -= 1
        return res

53. 最大子数组和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [0] * n
        dp[0] = nums[0]
        # dp 以下标 i 结尾的最大和的连续子数组
        for i in range(1, n):
            if dp[i-1] > 0:
                dp[i] = dp[i-1] + nums[i]
            else:
                dp[i] = nums[i]
        return max(dp)

912. 排序数组

# python
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        def quick_sort(a, l, r):
            if l >= r: return a
            i = l - 1; j = r + 1; x = a[l + r >> 1]
            while i < j:
                i += 1
                while a[i] < x: i += 1
                j -= 1
                while a[j] > x: j -= 1
                if i < j: a[i], a[j] = a[j], a[i]
            quick_sort(a, l, j); quick_sort(a, j+1, r)
            return a
        return quick_sort(nums, 0, len(nums)-1)
 
# python 模拟 c++ do while 循环
# while True: do() if fail_condition: break
# do(); while condtion: do()

21. 合并两个有序链表

# 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, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        head = cur = ListNode(0)
        while list1 and list2:
            if list1.val <= list2.val:
                cur.next = list1
                list1 = list1.next
            else:
                cur.next = list2
                list2 = list2.next
            cur = cur.next
        # 合并后 list1 和 list2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        cur.next = list1 if list1 else list2
        return head.next

1. 两数之和

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        # 遍历列表同时查字典
        map = dict()
        for i, n in enumerate(nums):
            m = target - n
            if m in map:
                return [map[m], i]
            else:
                map[n] = i # 这句不能放在if语句之前,解决list中有重复值或target-num=num的情况
 

102. 二叉树的层序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res = []
        q = [root]
        while q:
            tmp = []
            for i in range(len(q)):
                node = q.pop(0)
                tmp.append(node.val)
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            res.append(tmp)
        return res

5. 最长回文子串

class Solution:
    def palindrome(self, s: str, left: int, right: int) -> str:
        while(left>=0 and right<len(s) and s[left]==s[right]):
            left-=1
            right+=1
        return s[left+1:right]
 
    def longestPalindrome(self, s: str) -> str:
        res=""
        for i in range(len(s)):
		    #奇数回文子串
            s1 = self.palindrome(s,i,i)
			#偶数回文子串
            s2 = self.palindrome(s,i,i+1)
            res = res if len(res)>len(s1) else s1
            res = res if len(res)>len(s2) else s2
        return res

33. 搜索旋转排序数组

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if not nums: return -1
        l = 0; r = len(nums) - 1
        # 无重复数,在有序区间查找
        while l <= r:
            m = l + r >> 1
            if nums[m] == target: return m # 因为存在找不到的情况,故在此return
            # 可以用nums[l]和nums[m]判断有序,也可以用nums[m]和nums[r]判断有序
            elif nums[l] <= nums[m]: # 左半部分是有序
                # target落在左半部分有序区域内,去掉m
                if nums[l] <= target < nums[m]:
                    r = m - 1
                else:
                    l = m + 1
            else: # 右半部分是有序
                # target落在右半部分有序区域内,去掉m
                if nums[m] < target <= nums[r]:
                    l = m + 1
                else:
                    r = m - 1
        return -1
 
# 2.1
# 时间复杂度:O(logn)
# 空间复杂度:O(1)
 

121. 买卖股票的最佳时机

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minprice = float('inf')
        maxprofit = 0
        # 一次遍历
        for price in prices:
            minprice = min(minprice, price)
            maxprofit = max(maxprofit, price-minprice)
        return maxprofit

20. 有效的括号

class Solution:
    def isValid(self, s: str) -> bool:
        if len(s) % 2 == 1: return False
        dict = {'(':')','[':']','{':'}'}
        stack = list()
        # stack中存左括号。 如果是左括号, 加入栈中; 如果是右括号, 判断栈顶元素的键的值是否等于当前元素; 栈 stack 为空: 此时 stack.pop() 操作会报错
        for c in s:
            if c in dict: stack.append(c)
            elif not stack or dict[stack.pop()] != c: return False
        return not stack

141. 环形链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
 
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast: return True
        return False

88. 合并两个有序数组

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        res = []
        p1 = p2 = 0
        while p1 < m or p2 < n:
            if p1 == m:
                res.append(nums2[p2])
                p2 += 1
            elif p2 == n:
                res.append(nums1[p1])
                p1 += 1
            elif nums1[p1] <= nums2[p2]:
                res.append(nums1[p1])
                p1 += 1
            else:
                res.append(nums2[p2])
                p2 += 1
        nums1[:] = res
        

103. 二叉树的锯齿形层序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res = []
        q = [root]
        cnt = 0
        while q:
            tmp = []
            for i in range(len(q)):
                node = q.pop(0)
                tmp.append(node.val)
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            if cnt%2 == 0: res.append(tmp)
            else: res.append(tmp[::-1])
            cnt += 1
        return res

200. 岛屿数量

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        def dfs(grid, i, j):
            if not (0 <= i < len(grid) and 0 <= j < len(grid[0])): return
            if grid[i][j] != '1': return
            grid[i][j] = '2'; # 将格子标记为「已遍历过」 
            dfs(grid, i - 1, j)
            dfs(grid, i + 1, j)
            dfs(grid, i, j - 1)
            dfs(grid, i, j + 1)
        res = 0
        m, n = len(grid), len(grid[0])
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    dfs(grid, i, j)
                    res += 1
        return res

236. 二叉树的最近公共祖先

# Definitio
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值